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

Node.js中MongoDB事务实现咨询:多集合更新及session疑问

MongoDB事务改造落地示例及Session来源解答

一、事务改造后的可运行代码

注意:MongoDB事务仅支持副本集或分片集群部署,单节点实例无法使用事务功能。以下是基于你的代码改造后的完整事务实现(假设使用Mongoose连接MongoDB):

async function stockItemAdd(req, res) {
  let session;
  try {
    // 创建事务会话
    session = await mongoose.startSession();
    // 开启事务
    session.startTransaction();

    // 绑定会话执行第一个更新操作
    const collection_1 = await Inventory.findOneAndUpdate(
      { _id: '1' },
      { 
        $set: {
          name: 'red_box',
          catalogNumber: 'AAA',
          quantity: req.body.quantity
        }
      },
      { session, new: true } // 必须传入session绑定事务上下文
    ).exec();

    // 绑定会话执行第二个更新操作
    const collection_2 = await Stock.findOneAndUpdate(
      { catalogNumber: 'AAA' },
      { $inc: { quantity: req.body.quantity } },
      { session, new: true }
    ).exec();

    // 提交事务:两个操作都成功才会持久化到数据库
    await session.commitTransaction();
    res.status(200).json({ success: true, data: { collection_1, collection_2 } });
  } catch (error) {
    // 回滚事务:任一操作失败则撤销所有变更
    if (session) await session.abortTransaction();
    res.status(500).json({ success: false, error: error.message });
  } finally {
    // 结束会话释放资源
    if (session) session.endSession();
  }
}

核心注意点:

  • 所有事务内的数据库操作必须传入session参数,绑定到同一个事务上下文
  • 用try/catch捕获异常,一旦出错立即回滚事务
  • 事务完成后必须调用endSession()释放会话资源

二、视频中Session的来源

视频34分46秒展示的session,是从MongoDB客户端(不管是官方Node.js驱动的MongoClient,还是Mongoose封装的客户端)通过startSession()方法创建的。

这个session是事务的核心载体——所有属于同一事务的读写操作,都必须绑定到这个session上,MongoDB才会将这些操作视为一个原子单元,保证要么全部成功提交,要么全部失败回滚。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 08:40:05