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

Mongoose模型无法访问进行中事务连接的问题排查

MongoDB多文档事务报错解决方案:Given transaction number 1 does not match any in-progress transactions

首先先明确你的第一个假设:后续路由中引入的模型都指向同一已连接的连接,这个假设是正确的。因为Mongoose是单例模式,所有通过mongoose.model()创建的模型都会默认绑定到Mongoose的当前连接上,只要你只建立了一个数据库连接,所有路由里的模型都会共享这个连接。

接下来我们分析报错原因并给出具体解决方案:

核心问题分析

你遇到的事务编号不匹配错误,主要是因为手动管理事务生命周期(启动、提交、回滚)时容易出现上下文不一致,再加上代码里存在一个容易被忽略的语法错误,共同导致了事务异常。

具体解决方案

1. 修正数据库连接文件(./db/index.ts)

首先修正state对象的语法错误,同时简化连接逻辑,确保存储的是实际的MongoDB连接对象:

const fs = require('fs');
const path = require('path');
const mongoose = require('mongoose');

// 修正对象属性赋值语法(将=改为:)
const state = { connection: null };

// 加载所有模型(模型会自动注册到Mongoose的默认连接)
const modelFiles = fs.readdirSync(path.join(__dirname, 'models'));
modelFiles
 .filter(fn => fn.endsWith('.js') && fn !== 'index.js')
 .forEach(fn => require(path.join(__dirname, 'models', fn)));

const connect = async () => {
 // 连接数据库,成功后直接存储实际的连接对象
 await mongoose.connect('你的数据库连接字符串');
 state.connection = mongoose.connection;
 return;
}

const get = () => state.connection;

module.exports = { connect, get };

2. 修正路由事务逻辑

使用Mongoose推荐的session.withTransaction()方法自动管理事务生命周期,同时修正更新操作符的错误:

const ExampleModel = require('../db/models/example.model');
const db = require('../db/index');

router.post('/changeQty', async (req,res,next) => {
 const connection = db.get();
 const session = await connection.startSession();
 const { someData } = req.body.data;

 try {
  // 使用withTransaction自动处理事务的启动、提交、回滚
  await session.withTransaction(async () => {
    const promiseArr = someData.map(data => 
      ExampleModel.findOneAndUpdate(
        { _id: data.id },
        { $inc: { qty: data.qty } }, // 修正错误操作符:$incr → $inc
        { new: true, runValidators: true }
      ).session(session) // 绑定当前事务会话
    );
    await Promise.all(promiseArr);
  });

  return res.status(200).json({ message: '库存更新成功' });
 } catch(err) {
  console.error('事务执行失败:', err);
  return res.status(500).json({ err: err.message });
 } finally {
  session.endSession();
 }
})

关键说明

  • withTransaction()方法会自动处理事务的全生命周期,避免手动调用startTransaction、commitTransaction、abortTransaction时可能出现的上下文不一致问题。
  • 你代码里的$incr是错误的MongoDB操作符,正确的自增操作符是$inc,这个错误会导致更新操作失败,间接触发事务异常。
  • 所有模型操作必须通过.session(session)绑定到当前事务会话,确保操作在事务上下文内执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 03:53:37