Appearance
MongoDB 原子操作
单文档原子性
对单个文档的写操作(如 updateOne、findOneAndUpdate、replaceOne)是原子的:要么完整生效,要么不生效,不会出现“改了一半”的中间状态。
javascript
db.counters.updateOne(
{ _id: "pageViews" },
{ $inc: { count: 1 } }
)上述自增在同一文档内是原子的。
多文档事务(Transaction)
需要对多个文档或多个集合保持原子性时,可使用 事务(需副本集或分片集群,且 MongoDB 4.0+):
javascript
const session = client.startSession();
session.startTransaction();
try {
db.orders.insertOne({ ... }, { session });
db.inventory.updateOne({ ... }, { $inc: { qty: -1 } }, { session });
await session.commitTransaction();
} catch (e) {
await session.abortTransaction();
} finally {
session.endSession();
}事务内所有写都在同一 session 上执行,提交时一起提交,失败可回滚。
设计建议
- 能用一个文档表达的逻辑,尽量用单文档 + 更新操作符(如
$inc、$push)保证原子性。 - 必须跨文档时再使用事务,并注意事务有性能与限制(见官方文档)。下一节介绍 MongoDB 高级索引。