gpt4 book ai didi

mongodb - mongoose 模型无法访问正在进行的事务的连接

转载 作者:可可西里 更新时间:2023-11-01 09:14:43 34 4
gpt4 key购买 nike

在我当前的 express 应用程序中,我想使用 mongodb 多文档事务的新功能。

首先指出我如何连接和处理模型很重要

我的 app.js(服务器)首先使用 db.connect() 连接到数据库。

我需要我的 db.index 文件中的所有模型。由于模型将使用相同的 Mongoose 引用启动,我假设 future 不同 route 模型的需求指向已连接和相同的连接。如果我对这些假设有任何错误,请纠正我。

我将连接引用保存在状态对象中,并在以后的事务需要时返回它

./db/index.ts

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

const state = {
connection = null,
}

// require all models
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 () => {
state.connection = await mongoose.connect(.....);
return;
}

const get = () => state.connection;

module.exports = {
connect,
get,
}

我的模型文件包含我需要的模式

./db/models/example.model.ts

const mongoose   = require('mongoose');
const Schema = mongoose.Schema;
const ExampleSchema = new Schema({...);

const ExampleModel = mongoose.model('Example', ExampleSchema);
module.exports = ExampleModel;

现在是我尝试进行基本交易的路线。 F

./routes/item.route.ts

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

router.post('/changeQty', async (req,res,next) => {

const connection = db.get().connection;
const session = await connection.startSession(); // works fine

// start a transaction
session.startTransaction(); // also fine

const {someData} = req.body.data;

try{

// jsut looping that data and preparing the promises
let promiseArr = [];
someData.forEach(data => {
// !!! THIS TRHOWS ERROR !!!
let p = ExampleModel.findOneAndUpdate(
{_id : data.id},
{$incr : {qty : data.qty}},
{new : true, runValidators : true}
).session(session).exec();
promiseArr.push(p);
})

// running the promises parallel
await Promise.all(promiseArr);

await session.commitTransaction();

return res.status(..)....;

}catch(err){
await session.abortTransaction();
// MongoError : Given transaction number 1 does not match any in-progress transactions.
return res.status(500).json({err : err});
}finally{
session.endSession();
}

})

但我总是得到以下错误,这可能与我的模型的连接引用有关。我假设,他们无权访问启动 session 的连接,因此他们不知道该 session 。

MongoError: Given transaction number 1 does not match any in-progress transactions.

也许我需要以某种方式在 db.connect 中使用直接连接引用启动模型?

某处犯了一个大错误,我希望你能引导我走上正确的道路。我感谢任何帮助,提前致谢

最佳答案

这是因为您正在并行执行操作:

所以你有一堆竞争条件。只需使用 async/await

让您的生活更轻松。

let p = await ExampleModel.findOneAndUpdate(
{_id : data.id},
{$incr : {qty : data.qty}},
{new : true, runValidators : true}
).session(session).exec();

引用:https://github.com/Automattic/mongoose/issues/7311

如果这不起作用,请尝试一个接一个地执行 promise ,而不是 promise.all()

关于mongodb - mongoose 模型无法访问正在进行的事务的连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54768847/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com