Skip to content

MongoDB 原子操作

单文档原子性

单个文档的写操作(如 updateOnefindOneAndUpdatereplaceOne)是原子的:要么完整生效,要么不生效,不会出现“改了一半”的中间状态。

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 高级索引