0

嗨,
我正在从节点 js 运行 eval 脚本,使nolocktrue 禁用全局锁。我从 java 运行的相同 eval 脚本也使用 nolock true。

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 中使用命令查询,但我遇到了同样的问题。

4

1 回答 1

0

默认情况下,eval 函数本身将获取并持有一个全局写锁。通过设置nolock为 true,您所做的就是防止该锁被 eval 占用。设置nolock不会影响 JavaScript 代码本身的操作是否需要写锁,因此您在代码本身中执行的任何更新、插入、findAndModify 等操作仍将像任何其他写操作一样获取锁(供参考,这是基本上直接来自文档)。

没有其他选择或解决方法,您不能在不影响锁定的情况下将数据写入数据库,如果您正在写入数据(包括更新),那么您必须使用写锁。在 eval 语句中运行操作服务器端并不会改变这一点。

值得注意的是,您发布的警告消息只是警告。这意味着有问题的查询试图让步(通常是因为它对磁盘造成了错误)并且由于它当时持有的锁的性质而不能——这不是错误。我建议在 eval 块之外运行它以查看它的外观,然后将 eval 从等式中完全删除。

于 2014-11-27T16:22:33.660 回答