0

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

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

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

4

1 回答 1

5

许多开发人员会建议使用evalis "evil",因为在 MongoDB 实例的上下文中执行可能未经处理的 JavaScript 代码是明显的安全问题。通常 MongoDB 对这些类型的注入攻击是免疫的。

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

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

对于部分完成eval操作可能导致数据库损坏的情况,我建议考虑替代模式设计并避免eval. 这并不是说它在 99.9999% 的时间里都行不通,这真的取决于你最终决定是否值得冒险。

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

{ version: 7, isCurrent: true} 

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

  • 创建包含当前版本的第二个文档,这将是一个原子集操作。这意味着所有读取都可能需要先读取“查找当前版本”文档,然后再读取完整文档。
  • 使用时间戳代替boolean值。根据时间戳查找最新文档(一旦设置了当前文档,如果需要,您的代码可以清除旧文档的字段)
于 2013-04-05T18:23:53.813 回答