You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB事务隔离问题:外部修改读取数据后事务是否自动终止?

MongoDB事务中外部修改读取数据的行为说明
  • 默认情况下,你的事务不会自动终止。MongoDB事务默认采用快照隔离级别:事务启动时会生成一个数据快照,事务内所有读操作都基于这个快照执行,外部在事务期间对数据的写入修改,不会影响事务内的读结果,也不会触发事务自动中止。
  • 回到你的代码示例:find操作读取的是事务启动时的快照数据,即便外部修改了符合qty: {$gt:4}条件的文档,事务后续的update操作依然会正常执行,不会因为外部的写入操作而自动终止。
  • 如果需要实现“读取的数据被外部修改则中止事务”的逻辑,需要手动实现乐观锁机制:
    1. 读取数据时,同时记录文档的版本标识(比如自定义的version字段,或者MongoDB内置的更新时间戳)
    2. 执行更新操作时,将版本标识作为更新条件的一部分
    3. 检查更新操作的返回结果,如果没有匹配到任何文档,说明数据已被外部修改,此时手动抛出错误终止事务

手动实现乐观锁的示例代码:

await session.withTransaction(async () => {
  const coll1 = client.db('mydb1').collection('foo');

  // 读取目标文档及版本号
  const targetDoc = await coll1.findOne({ qty: { $gt: 4 } }, { session });
  if (!targetDoc) return;
  const originalVersion = targetDoc.version;

  // 事务内的中间业务逻辑
  // ...

  // 更新时校验版本,确保数据未被外部修改
  const updateRes = await coll1.updateOne(
    { id: 3, version: originalVersion },
    { $set: { qty: 2 }, $inc: { version: 1 } },
    { session }
  );

  // 无匹配文档则手动终止事务
  if (updateRes.modifiedCount === 0) {
    throw new Error("数据已被外部修改,事务中止");
  }
}, transactionOptions);

内容的提问来源于stack exchange,提问作者Paulo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 10:17:13