Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb 埃瓦尔就是那个恶魔吗?_Mongodb_Eval - Fatal编程技术网

Mongodb 埃瓦尔就是那个恶魔吗?

Mongodb 埃瓦尔就是那个恶魔吗?,mongodb,eval,Mongodb,Eval,我知道锁会锁定整个数据库,这对吞吐量来说不太好——但是我有一个场景,涉及多个文档的非常特定的事务必须被隔离 因为该事务不经常发生,而且相当快(对索引查询进行了一些更新),所以我考虑使用eval来执行它 他们有什么我应该注意的陷阱吗(我看到过一些eval=邪恶的帖子,但没有太多解释)? 如果数据库是副本集的一部分,这会有区别吗?许多开发人员建议使用eval是“邪恶的”,因为他们明显担心在MongoDB实例的上下文中执行可能未初始化的JavaScript代码会带来安全问题。通常MongoDB对这些类

我知道锁会锁定整个数据库,这对吞吐量来说不太好——但是我有一个场景,涉及多个文档的非常特定的事务必须被隔离

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

他们有什么我应该注意的陷阱吗(我看到过一些eval=邪恶的帖子,但没有太多解释)?

如果数据库是副本集的一部分,这会有区别吗?

许多开发人员建议使用
eval
是“邪恶的”,因为他们明显担心在MongoDB实例的上下文中执行可能未初始化的JavaScript代码会带来安全问题。通常MongoDB对这些类型的注射攻击免疫

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

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

对于部分完成的
eval
操作可能导致数据库损坏的情况,我建议考虑替代方案设计并避免
eval
。这并不是说它在99.9999%的情况下都不起作用,而是由你最终决定是否值得冒险

在您描述的案例中,有几个选项:

{ version: 7, isCurrent: true} 
version 8
文档变为当前文档时,例如,您可以:

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

许多开发人员会建议使用
eval
是“邪恶的”,因为他们明显担心在MongoDB实例的上下文中执行可能未初始化的JavaScript代码会带来安全问题。通常MongoDB对这些类型的注射攻击免疫

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

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

对于部分完成的
eval
操作可能导致数据库损坏的情况,我建议考虑替代方案设计并避免
eval
。这并不是说它在99.9999%的情况下都不起作用,而是由你最终决定是否值得冒险

在您描述的案例中,有几个选项:

{ version: 7, isCurrent: true} 
version 8
文档变为当前文档时,例如,您可以:

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

eval是邪恶的,因为在几乎任何语言/环境中,它都相当于站在街上,随意邀请路人进入你的房子,并说“别拘束”。除非你非常小心,并且考虑了所有可能的结果,否则eval可以很容易地开始一些无法阻止的事情?你到底打算运行什么?@AsyaKamsky我有一个类似于
{version:7,isCurrent:true}
的文档当我插入一个版本为
version:8
的新文档时,我需要在该新文档上将
isCurrent
设置为true,在所有其他文档上设置为false,以便在任何时候,最多有一个文档具有
isCurrent:true
(实际用例更复杂,但这是基本思想,是一个相当困难的要求)。因此它看起来像
db.eval(function(){db.coll.find({}).forEach(function(e){e.isCurrent=(e.current==e.version);db.coll.save(e);})。您是否考虑过如果操作中途失败会发生什么情况?数据库中没有回滚