Mongodb eval nolock:是的

时间:2014-11-27 10:02:02

标签: java node.js mongodb eval nolock

您好,
 我正在从节点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中使用命令查询,但我遇到了同样的问题。

1 个答案:

答案 0 :(得分:0)

默认情况下,eval函数本身将获取并保持全局写锁定。通过将nolock设置为true,您所做的就是阻止eval采取锁定。设置nolock不会影响JavaScript代码本身内的操作是否采用写锁定,因此您在代码本身中执行的任何更新,插入,查找和修改等操作仍将像其他任何写操作一样进行锁定(作为参考,这基本上是straight from the docs)。

除此之外别无选择或方法,您无法在不影响锁定的情况下将数据写入数据库,如果您正在编写数据(包括更新),则必须执行写锁定。运行操作服务器端和eval语句内部不会改变它。

值得注意的是,您发布的警告信息只是一个警告。这意味着有问题的查询试图屈服(通常是因为它对磁盘造成了故障)而且由于当时它所持有的锁的性质而无法实现 - 这不是错误。我建议在eval块之外运行它以查看它的外观然后完全从等式中删除eval。