您好,
我正在从节点js运行eval脚本,使nolock
为true以禁用全局锁。我从java运行的同样的eval脚本也使用nolock为真。
String jsFunction = "function(){"
+ "var uid = 12;"
+ "return refreshList(uid,false);}";
DBObject commandObj = new BasicDBObject();
commandObj.put("eval", jsFunction);
commandObj.put("nolock", true);
CommandResult status =db.command(commandObj);
db.eval("function (x, isoverwrite) { return refreshList(x, isoverwrite);}", [21,isoverwrite] ,{nolock:true}, function(err, result){
});
在java中运行脚本时,db中没有锁定,我可以同时运行查询。但是在运行上面代码的节点js中,我无法同时执行其他进程。我无法看到锁定登录mongodb控制台也。我不知道为什么两者的行为都会发生变化。我也尝试在节点js中使用命令查询,但我遇到了同样的问题。
答案 0 :(得分:0)
默认情况下,eval函数本身将获取并保持全局写锁定。通过将nolock
设置为true,您所做的就是阻止eval采取锁定。设置nolock
不会影响JavaScript代码本身内的操作是否采用写锁定,因此您在代码本身中执行的任何更新,插入,查找和修改等操作仍将像其他任何写操作一样进行锁定(作为参考,这基本上是straight from the docs)。
除此之外别无选择或方法,您无法在不影响锁定的情况下将数据写入数据库,如果您正在编写数据(包括更新),则必须执行写锁定。运行操作服务器端和eval语句内部不会改变它。
值得注意的是,您发布的警告信息只是一个警告。这意味着有问题的查询试图屈服(通常是因为它对磁盘造成了故障)而且由于当时它所持有的锁的性质而无法实现 - 这不是错误。我建议在eval块之外运行它以查看它的外观然后完全从等式中删除eval。