MongoDB 更新 $isolated

MongoDB update with $isolated

我想知道这两个查询之间的区别:

myCollection.update (    {
      a:1,
      b:1,
      $isolated:1    } );

myCollection.update (    {
      $and:
      [ 
        {a:1},
        {b:1},
        {$isolated:1}
      ]    } );

基本上,我需要为所有具有 'a=1 and b=1' 的文档执行带有 $isolated 的 .update()。我对如何编写“$isolated”参数以及如何确保查询正常工作感到困惑。

我基本上会质疑您声明中的 "need to perform",尤其是考虑到缺少 { multi: true } 您打算匹配和更新大量文档的地方。

这里的第二个考虑因素是您提出的声明根本没有任何类型的更新操作。这可能是你问的关于 "difference" 的问题的结果,但考虑到你目前对 MongoDB 查询操作与 $and 用法的明显理解,那么我严重怀疑你"need"这个都没有。

所以"If"你真的需要这样写一个声明,那么它应该是这样的:

myCollection.update(
   { "a": 1, "b": 1, "$isolated": true },
   { "$inc": { "c": 1 } },
   { "multi": true }
)

但是你真正"need"要理解的是那是在做什么。

本质上,此查询将导致 MongoDB 持有 "write lock",至少在集合级别。这样在整个wtite完成之前不能进行其他操作。这也确保了在那之前,所有读取尝试只会看到文档在进行任何更改之前的状态,直到该操作完全完成,然后后续读取才能看到所有更改。

这可能 "sound tempting" 对某些人来说是个好主意,但事实并非如此。写锁会影响更新的并发性,通常是一件需要避免的坏事。您可能还会将其与 "transaction" 混淆,但事实并非如此,因此 任何 执行期间的失败只会在失败的地方停止操作。这不会 "undo" 在 $isolated 块中进行的更改,它们将保持提交状态。

这里几乎唯一有效的用例是,您 "absolutely need"all 的元素是修改匹配 "a" 和 "b" 以在某些东西是 "aggregating" 的情况下保持一致的状态,该组合与此操作完全相同 运行。在这种情况下,然后公开 "partially" 改变的 "c" 值可能是不可取的。但是这个的使用范围很窄,一般的应用一般不需要这样的一致性。

回到 $and 的用法,所有 MongoDB 参数无论如何都是隐含的 $and 操作,除非它们被明确声明。 $and 唯一的一般用法是您需要在同一个文档键上使用多个条件。即便如此,通常最好写在评估的 "right side" 上,例如 $gt$lt:

{ "a": { "$gt": 1, "$lt": 3 } }

完全相同:

{
    "$and": [
        { "a": { "$gt": 1 } },
        { "b": { "$lt": 3 } }
    ]
}

所以真的很多余

最后,如果你真正想做的是:

myCollection.update(
   { "a": 1, "b": 1 },
   { "$inc": { "c": 1 } },
)

更新单个文档,那就根本不需要$isolated了。在这里获得显式锁实际上只是为原本不需要的简单操作增加了复杂性。即使是批量,您可能真的不需要通过获取锁提供的一致性,因此可以简单地再次执行:

myCollection.update(
   { "a": 1, "b": 1 },
   { "$inc": { "c": 1 } },
   { "multi": true }
)

这将很高兴地允许写入所有选定的文档并读取 "latest" 信息。一般来说,"you want this" as "atomic" 运算符,比如 $inc 无论如何都会修改他们看到的现值。

因此,在 "multi" 写入发现所有匹配项中的文档之前,另一个进程是否匹配这些文档之一并不重要,因为 "both" $inc 操作将要执行反正。所有 $isolated 在这里真正做的是 "ensure" 当这个操作开始时,然后 "it's" 写入将是 "first" 提交,然后在锁定期间任何尝试都会发生 "after",而不是每个操作何时能够获取该文档并进行修改的一般顺序。

在 9/10 的情况下,最终结果是相同的。例外是这里获得的 "write lock","will" 减慢其他操作。