You need to enable JavaScript to run this app. Mongoose实现事务时报session.withTransaction、endSession不是函数
优惠活动
大模型
产品
解决方案
定价
更多

Mongoose实现事务时报session.withTransaction、endSession不是函数

触发报错的核心问题点
  • 会话创建逻辑存在根本性错误:startSession()是异步方法,原代码调用时未添加await,实际拿到的是未完成初始化的Promise对象,而非真正的MongoDB客户端会话实例,因此不存在withTransaction、endSession方法,直接触发两个TypeError报错。
  • 连接对象获取路径错误:mongoose.connect()的返回值是Mongoose全局实例,并非底层MongoClient实例,直接在Mongoose实例/连接对象上调用startSession不符合MongoDB驱动的调用规范。
  • 事务操作未绑定会话:即使会话创建正常,执行updateOne等数据库操作时未传入对应会话参数,操作不会被纳入事务管理范围,无法触发失败回滚逻辑。
  • 版本兼容适配问题:session.withTransaction自动重试辅助方法依赖Mongoose 5.2.0、对应mongodb驱动3.1.0及以上版本,若依赖版本过低也会触发方法不存在的报错。
修正后的可运行事务实现

实现前需先确认本地Mongoose版本≥5.2.0,可通过npm list mongoose命令查看版本,低版本需先完成升级。

// 基础配置
const CONSTANTS = {
  ADMIN_MONGO_URL: "mongodb://localhost:27017/admin?retryWrites=true&w=majority"
}
const mongoose = require('mongoose');
// 定义项目模型Schema
const mongooseProjectSchema = new mongoose.Schema({
  uuid: String,
  clientID: String,
  accumulatedProj: Array
})

async function transactionCreateProject(newProjectJson) {
  const mongoConnectConfig = {
    useNewUrlParser: true,
    useUnifiedTopology: true, 
    useCreateIndex: true
  };
  // 建立数据库连接
  await mongoose.connect(CONSTANTS.ADMIN_MONGO_URL, mongoConnectConfig)
  const db = mongoose.connection;
  db.on('error', console.error.bind(console, 'MongoDB连接错误:'))
  const projectModel = mongoose.model('project', mongooseProjectSchema)

  // 修正1:从底层MongoClient实例创建会话,通过await等待会话初始化完成
  const client = mongoose.connection.getClient();
  const session = await client.startSession();

  const transactionOptions = {
    readPreference: 'primary',
    readConcern: { level: 'local' },
    writeConcern: { w: 'majority' }
  };

  let transactionResult = null;
  try {
    // 修正2:会话实例上可正常调用withTransaction方法
    transactionResult = await session.withTransaction(async () => {
      // 修正3:数据库操作显式传入会话参数,将操作纳入事务范围
      const updateRes = await projectModel.updateOne(
        {'uuid': newProjectJson['clientID']}, 
        {$push: {'accumulatedProj': {'uuid': newProjectJson.uuid}}},
        { session: session }
      );
      console.log("事务内更新操作执行结果:", updateRes)
      // 可在回调内直接返回需要向外传递的结果,供事务外层逻辑读取
      return updateRes;
    }, transactionOptions);

    if (transactionResult) {
      console.log("事务执行成功,所有操作已正常提交");
    } else {
      console.log("事务被主动中止");
    }
  }
  catch (e) {
    console.log("事务因异常中止,所有操作已自动回滚:" + e.message);
  }
  finally {
    // 修正4:会话实例上可正常调用endSession方法释放资源
    await session.endSession();
  }

  return transactionResult;
}
前置验证注意事项
  • 确认MongoDB副本集状态正常,可通过mongo shell执行rs.status()查看节点状态,确保副本集存在可用的PRIMARY节点,独立部署的单节点MongoDB不支持事务能力。
  • 若升级Mongoose后仍报方法不存在,可通过npm ls mongodb检查嵌套依赖的mongodb驱动版本,确保驱动版本≥3.1.0。

内容的提问来源于stack exchange,提问作者Sam Min Wong

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.30 09:15:04