原子性和事务
原子性(Atomicity)
在 MongoDB 中,写入操作在单个文档级别上是 原子性的,即使该操作修改单个文档中的多个嵌入文档也是如此。
多文档事务
当单个写入操作(例如 db.collection.updateMany()
)修改了多份文档,则每份文档的修改都是原子性的,但整个操作不是原子性的。
在执行多文档写入操作时,无论是通过单次写入操作还是多次写入操作,其他操作都可能会交错进行。
对于需要对多个文档(在单个或多个集合中)原子性读取和写入的情况,MongoDB 支持分布式事务,包括副本集和分片集群上的事务。
有关详细信息,请参阅事务。
重要
在大多数情况下,与单文档写入操作相比,分布式事务会产生更高的性能成本,并且分布式事务的可用性不应取代有效的模式设计。在许多情况下,非规范化数据模型(嵌入式文档和数组)仍然是数据和使用案例的最佳选择。换言之,对于许多场景,适当的数据建模将最大限度地减少对分布式事务的需求。
有关其他事务使用注意事项(如运行时间限制和 oplog 大小限制),另请参阅生产注意事项。
并发控制
并发控制允许多个应用程序同时运行,而不会造成数据不一致或数据冲突。
对文档的 findAndModify
操作是原子性操作:如果查找条件与文档匹配,则对该文档执行更新。在当前更新完成之前,该文档的并发查询和其他更新不会受影响。
考虑以下示例:
一个包含两个文档的集合:
db.myCollection.insertMany( [ { _id: 0, a: 1, b: 1 }, { _id: 1, a: 1, b: 1 } ] ) 两个如下
findAndModify
操作同时运行:db.myCollection.findAndModify( { query: { a: 1 }, update: { $inc: { b: 1 }, $set: { a: 2 } } } )
完成 findAndModify
操作后,保证两份文档中的 a
和 b
都设置为2
。
您还可对字段创建唯一索引,以使其仅拥有唯一值。此举可防止插入和更新操作创建重复数据。您可对多个字段创建唯一索引,以确保字段值的组合是唯一的。有关示例,请参阅附带唯一索引的 findAndModify() Upsert。