原子性 & 事务
原子性
在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 with Unique Index。