mongodb 避免不一致

mongodb avoid inconsistencies

给定以下场景:

带有文档 Product(id, owner) 和文档 p1(1, "bob") 的集合产品

两次更新都会成功,对吗?据我所知,结果将是 "laura" MongoDB。但是,我是否可以通过添加一个 where 子句 name="bob" 来简单地解决这个问题,因为更改在一个文档中,或者我是否需要更高级的功能,例如交易?或者这仅适用于多文档更新?

Both updates will succeed, correct?

是的。

假设更新方法是这样的:db.collection.updateOne( { id: 1 }, { owner: name } ),其中 id 是唯一的产品 ID 字段,"name" 值是 "laura" 或 "karen" 根据要求。两次更新都会成功。

但是,最终 结果可能是 "laura" 或 "karen"。您不知道哪个更新将首先到达数据库。因此,无法保证更新后文档中 owner 的值是多少。

请注意,读取和更新是两个独立的操作(如在 CRUD 中)。阅读文档并不意味着请求以任何方式拥有该文档。文档说 "In MongoDB, an operation on a single document is atomic";这也适用于更新操作。

And the result will be "laura" as far as I understand MongoDB.

可能是。

除非您以某种方式控制数据库中更新的顺序,否则无法保证最终结果。

However, can I simply resolve this by adding a where clause name="bob" because the changes are in one document, or do I need more advanced features such as transactions? Or is this only for multi document updates?

添加一个像这样的 where 子句 db.collection.updateOne( { id: 1, owner: "bob"}, { owner: name } ) 将确保只发生一次更新操作。同样,不能保证会发生哪个更新。

Transactions?

事务只能与副本集(MongoDB 4.0+ 版)和分片集群(MongoDB 4.2+ 版)一起使用;不适用于独立 MongoDB 安装。

您的上述场景的应用是否需要交易?不。更新是单个操作,MongoDB 保证它是一个原子操作。通常,当有多个 CRUD 操作作为一个单元执行时(例如,发票生成可能会创建发票文档并更新库存和帐户集合——所有操作作为一个单元发生或根本不发生),事务通常很有用。