【问题标题】:MongoDB update multiple documentsMongoDB 更新多个文档
【发布时间】:2012-05-09 15:07:23
【问题描述】:

架构:

{
    name: String,
    available: Boolean,
    for: String
}

有“一个”:

{
    name: "a",
    available: true,
    for: ["b", "c"]
}

和“b”:

{
    name: "b",
    available: true,
    for: ["a", "b]
}

如果我更新 a.available = false,我应该同时更新 b.available = false。 如何更新两个文档并确保在更新“a”和“b”之间不会有其他进程/线程获得“b”。

【问题讨论】:

    标签: mongodb transactions


    【解决方案1】:

    MongoDB 不支持原子事务。因此,如果您需要在第二次更新失败时使第一次更新“自行撤消”,那么您就不走运了。

    但是,在某些有限的情况下,MongoDB 确实支持独立更新。更新不是全部或全部,但 MongoDB 将保证在您的写入过程中没有其他人写入集合。

    几个主要注意事项:

    • 文档必须全部在同一个集合中
    • 必须在一个查询中全部指定更新

    根据您提供的示例,您的案例可能符合条件。

    Here 是描述独立更新的文档。

    基本上,当名称为“a”或“b”时,您需要发出类似于以下内容的更新,以原子方式将“available”设置为 false:

    db.blah.update({"name": {"$in": ["a", "b"]}, "$atomic": 1}, {"available": false});
    

    【讨论】:

    • 如果我想用不同的值原子地更新不同的文档。如果 name=="a" 则更新计数 = 1;如果 name=="b" 则更新计数 = 2。
    • 这可能是不可能的。正如我所说,此功能存在一些重大限制 - MongoDB 并不是真正为这类事情设计的。
    【解决方案2】:

    如果您真的需要它,可以在 mongodb 之上实现此逻辑(在您的应用程序中,或者更好地在 mongo 驱动程序的包装器中)。

    您要求隔离属性。实现这一目标的一种方法是使用MVCC 模式。这确实有点矫枉过正,但这是为了让您了解如果您确实需要 mongodb 和一些 ACID 属性,您可以做什么。

    描述了 MVCC 模式的通用实现 here。 github 上还有一个project 用于实现这个,但它是一个java 项目。

    您可能还会看到此SO question 及其答案。我现在的回答只是一个总结。

    【讨论】:

      猜你喜欢
      • 2019-05-22
      • 1970-01-01
      • 2019-09-19
      • 2020-09-05
      • 1970-01-01
      • 2015-01-14
      • 2019-05-25
      • 2013-06-22
      • 2021-01-16
      相关资源
      最近更新 更多