4

架构:

{
    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”。

4

2 回答 2

5

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

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

几个主要的警告:

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

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

是描述隔离更新的文档。

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

db.blah.update({"name": {"$in": ["a", "b"]}, "$atomic": 1}, {"available": false});
于 2012-05-09T15:11:53.447 回答
3

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

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

此处描述了 MVCC 模式的通用实现。github上还有一个项目可以实现这个,但它是一个java项目。

您可能还会看到这个SO question和他们的答案。我现在的回答只是一个总结。

于 2012-05-10T08:10:13.197 回答