MongoDB 原子操作(Atomic Operations)
                           
天天向上
发布: 2025-03-09 09:30:35

原创
930 人浏览过

在 MongoDB 中,原子操作(Atomic Operations)指的是不可分割的操作,即要么完整执行,要么完全不执行,不会被其他操作干扰。MongoDB 的单文档操作是原子性的,但多文档操作默认不具备原子性,需要事务来保证。


1. MongoDB 单文档原子操作

MongoDB 对单个文档的操作是原子的,即在更新、删除或插入某个文档时,不会发生部分修改或竞态条件。

示例:原子性更新

db.products.updateOne(
  { _id: 1 },
  { $inc: { stock: -1 } } // 库存减少 1
)

即使多个用户同时更新 _id:1stock,MongoDB 也能确保每次更新是原子的,不会发生并发冲突。


2. 更新原子操作

MongoDB 提供了多种原子更新运算符,可在不覆盖整个文档的情况下更新字段。

$inc(自增/自减)

db.users.updateOne(
  { username: "Alice" },
  { $inc: { points: 10 } } // 增加 10 积分
)

$set(修改字段)

db.users.updateOne(
  { username: "Alice" },
  { $set: { status: "active" } } // 修改用户状态
)

$unset(删除字段)

db.users.updateOne(
  { username: "Alice" },
  { $unset: { tempField: "" } } // 删除 tempField 字段
)

$push(数组添加元素)

db.orders.updateOne(
  { _id: 101 },
  { $push: { items: "Keyboard" } }
)

$pull(数组删除元素)

db.orders.updateOne(
  { _id: 101 },
  { $pull: { items: "Mouse" } }
)

3. FindAndModify 原子性操作

findAndModify 是一个原子性操作,它可以查找并更新或删除文档,同时返回更新前或更新后的文档。

示例:原子性递增

db.counters.findAndModify({
  query: { _id: "orderId" },
  update: { $inc: { seq: 1 } },
  new: true
})

这个操作原子性地递增 seq 并返回新值,可用于实现自增 ID。


4. 多文档操作的原子性

MongoDB 默认不保证多文档更新的原子性,但可以通过事务(Transactions)实现。

示例:使用事务保证原子性

const session = db.getMongo().startSession();
session.startTransaction();
try {
  session.getDatabase("test").collection("accounts").updateOne(
    { username: "Alice" },
    { $inc: { balance: -100 } }
  );
  session.getDatabase("test").collection("accounts").updateOne(
    { username: "Bob" },
    { $inc: { balance: 100 } }
  );
  session.commitTransaction();
} catch (error) {
  session.abortTransaction();
}
session.endSession();

注意:事务仅适用于 MongoDB 4.0+ 的副本集,MongoDB 4.2+ 才支持分片事务


5. 原子操作的应用场景

场景解决方案
计数器自增$inc
乐观锁$set + version 字段
购物车更新$push / $pull
并发更新用户数据findAndModify
多表更新事务事务(Transactions)

6. 总结

  • MongoDB 的单文档操作是原子的,不会发生部分更新。
  • 使用 $inc$set$push$pull 等更新操作可原子性地修改数据
  • findAndModify 可确保查找 + 更新的原子性
  • 多文档更新不具备原子性,需要使用事务(Transactions)确保一致性。

更多详细内容请关注其他相关文章!

发表回复 0

Your email address will not be published. Required fields are marked *