【问题标题】:MongoDB multiple update isolationMongoDB多重更新隔离
【发布时间】:2018-04-19 16:21:29
【问题描述】:

我对 MongoDB 更新的工作方式感到困惑。

在以下文档中:https://docs.mongodb.com/manual/core/write-operations-atomicity/ 说:

在 MongoDB 中,写入操作在单个级别上是原子的 文档,即使操作修改了多个嵌入文档 在单个文档中。

当单个写入操作修改多个文档时, 每个文档的修改是原子的,但操作是一个整体 不是原子的,其他操作可能会交错。

我猜这意味着:如果我要更新文档的所有字段,我将无法看到部分更新:

  • 如果我在更新之前获得该文档,我将看到它没有任何变化
  • 如果我在更新后获得该文档,我将看到它的所有更改

对于多个元素,每个文档都会发生相同的行为。我想我们可以说每个文档更新都有一个事务,而不是所有文档更新的一个大事务。

但是假设有很多关于多次更新的文档,并且需要一段时间来更新所有这些文档。更新期间其他线程的查询会发生什么?

  • 他们会看到旧版本吗?或者他们会在更新完成之前被阻止?
  • 在这次大更新期间是否可以对相同文档进行其他更新?如果是这样,此中间更新是否会从大更新中排除某些文档?

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    他们会看到旧版本吗?或者他们会在更新完成之前被阻止?

    我猜其他线程可能会看到文档的旧版本或新版本,这取决于他们是在更新完成之前还是之后查询文档,但他们永远不会看到文档的部分更新(即一个字段已更改另一个没有改变)。

    在这次大更新期间可能对相同文档进行其他更新吗?如果是这样,这个中间更新是否会从大更新中排除某些文档?

    考虑 2 个线程对同一个文档进行更新,而不是大或小更新。线程 1 设置字段 {a:1, b:2} 和线程 2 设置 {b:3, c:4}。如果原始文档是{a:0, b:0, c:0},那么我们可以有两种情况:

    更新 1 在更新 2 之前执行: 该文档最终将是{a:1, b:3, c:4}

    更新 2 在更新 1 之前执行: 该文档最终将是{a:1, b:2, c:4}

    【讨论】:

    • 谢谢!这就解释了第一个问题:“他们会看到旧版本吗?或者他们会被阻止直到更新完成?”。你知道第二点会发生什么吗:“在这次大更新期间可能对同一文档进行其他更新?如果是这样,这个中间更新是否可以从大更新中排除某些文档?”
    • “在这次大更新期间,是否可以对同一文档进行其他更新?” => 是的,MongoDB AFAIK 中没有 big update 或(我猜你的意思是)transaction 这样的概念。 “这个中间更新会不会从大更新中排除一些文档?” => 我想是的;问题可以简化为“如果在游标遍历期间更新了某些文档,查询是否可以排除它们?”。如果您查看cursor.snapshot(),答案似乎是肯定的。
    • 有一个related post here
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多