Eval那邪恶吗?

ass*_*ias 0 eval mongodb

我知道eval锁定整个数据库,这对吞吐量不利 - 但是我有一个场景,必须隔离涉及多个文档的非常特定的事务.

因为该事务不经常发生并且相当快(对索引查询进行了一些更新),所以我正在考虑使用eval它来执行它.

他们应该注意到的任何陷阱(我看过几个eval =邪恶的帖子,但没有太多解释)?
如果数据库是副本集的一部分,它会有所不同吗?

Wir*_*rie 5

许多开发人员建议使用eval"邪恶",因为他们明显的安全问题是在MongoDB实例的上下文中执行的潜在未经过清理的JavaScript代码.通常,MongoDB不受那些类型的注入攻击的影响.

通过eval命令在MongoDB中使用JavaScript的一些性能问题在版本2.4中得到了缓解,因为多个JavaScript操作可以同时执行(取决于nolock选项的设置).但默认情况下,它需要一个全局锁定(这是你特别想要的).

当a eval用于尝试对多个文档执行(类似ACID)事务更新时,有一个主要问题.最大的问题是,如果所有操作都必须成功使数据处于一致状态,那么开发人员就会面临操作中途发生故障可能导致数据库部分完全更新的风险(如硬件故障)例如).根据正在执行的工作的性质,复制设置等,数据可能是正常的,也可能不是.

对于由于部分完成eval操作而可能发生数据库损坏的情况,我建议考虑另一种模式设计并避免eval.这并不是说它不会在99.9999%的时间内起作用,而是由你最终决定是否值得冒这个风险.

在您描述的情况下,有几个选项:

{ version: 7, isCurrent: true} 
Run Code Online (Sandbox Code Playgroud)

version 8文档成为最新文档时,您可以例如:

  • 创建包含当前版本的第二个文档,这将是一个原子集操作.这意味着所有读取可能需要先读取"查找当前版本"文档,然后读取完整文档.
  • 使用时间戳代替boolean值.根据时间戳查找最新文档(如果需要,当您设置当前文档时,您的代码可以清除旧文档的字段)