我理解eval
会锁定整个数据库,这对吞吐量不利 - 但是我的情况是必须隔离涉及多个文档的特定事务。
因为该事务不经常发生并且相当快(对索引查询进行了一些更新),所以我考虑使用eval
来执行它。
他们应该注意到的任何陷阱(我看过几个eval =邪恶的帖子,但没有太多解释)? 如果数据库是副本集的一部分,它会有所不同吗?
答案 0 :(得分:5)
许多开发人员建议使用eval
是“邪恶的”,因为他们明显的安全问题是在MongoDB实例的上下文中执行的潜在未经过清理的JavaScript代码。通常,MongoDB不受那些类型的注入攻击的影响。
通过eval
命令在MongoDB中使用JavaScript的一些性能问题在版本2.4中得到了缓解,因为多个JavaScript操作可以同时执行(取决于{{的设置) 1}}选项)。但是默认情况下,它需要一个全局锁定(这是你特别想要的)。
当使用nolock
尝试对多个文档执行(类似ACID)事务更新时,有一个主要问题。最大的问题是,如果所有操作都必须成功使数据处于一致状态,那么开发人员就会面临操作中途发生故障可能导致部分完全更新数据库的风险(如硬件故障)例如)。根据正在执行的工作的性质,复制设置等,数据可能是正常的,也可能不是。
对于因部分完成eval
操作而可能发生数据库损坏的情况,我建议考虑替代架构设计并避免使用eval
。这并不是说它不会在99.9999%的时间内起作用,而是由你最终决定是否值得冒这个风险。
在您描述的情况下,有几个选项:
eval
当{ version: 7, isCurrent: true}
文档成为最新文档时,您可以例如:
version 8
值。根据时间戳查找最新文档(如果需要,当您设置当前文档时,您的代码可以清除旧文档的字段)