mongodb - 猫鼬模型无法访问正在进行的事务的连接
问题描述
在我当前的 express 应用程序中,我想使用 mongodb 多文档事务的新功能。
首先,重要的是要指出我如何连接和处理模型
我的 app.js(服务器)首先使用 db.connect() 连接到数据库。
我需要我的 db.index 文件中的所有模型。由于模型将使用相同的 mongoose 引用启动,因此我假设未来对不同路由中的模型的需求指向已连接且相同的连接。如果我对这些假设中的任何一个有误,请纠正我。
我将连接引用保存在状态对象中,并在以后需要我的事务时返回它
./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();
}
})
但是我总是收到以下错误,这可能与我的模型的连接参考有关。我假设他们无权访问启动会话的连接,因此他们不知道会话。
MongoError:给定的事务编号 1 不匹配任何正在进行的事务。
也许我需要以某种方式使用直接连接引用启动 db.connect 中的模型?
某处有一个大错误,我希望你能引导我走向正确的道路。我很感激任何帮助,在此先感谢
解决方案
这是因为您正在并行执行操作:
所以你有一堆竞争条件。只需使用异步/等待
让您的生活更轻松。
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.all()。
推荐阅读
- postgresql - 在 PostgreSQL 中检查 UNIQUE 约束违规时的 UNACCENT
- javascript - Svelte todo 应用程序错误:标题属性返回未定义
- python - 如何在列表的块上循环运行函数?
- php - 今年在校学生的 Laravel 仪表板查询?
- excel - Documents.Open 用于嵌入的 Word 对象
- mongodb - MongoDB 是否像 Firebase 一样具有内置身份验证功能?
- regex - 我可以使用数据工厂数据流将列文本拆分为数组吗?
- asp.net-core - 在 ASP.NET Core MVC 中设置新的登录页面
- wordpress - Revolution Slider - 如何从一致的 URL 提供资源
- apache-kafka - 如何在 KSQL 中仅选择特定窗口中的数据?