В моем текущем экспресс-приложении я хочу использовать новую возможность многодокументных транзакций mongodb.
Прежде всего важно указать, как я подключаюсь и работаю с моделями
Мой app.js (сервер) сначала подключается к БД с помощью db.connect ().
Мне нужны все модели в моем файле db.index.Поскольку модели будут инициированы с использованием одной и той же ссылки мангуста, я предполагаю, что будущие потребности моделей на разных маршрутах указывают на подключенное и одно и то же соединение.Пожалуйста, исправьте меня, если я ошибаюсь с любым из этих предположений.
Я сохраняю ссылку на соединение внутри объекта состояния и возвращаю ее при необходимости позже для моей транзакции
. / 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
. / Routs / 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 с помощью ссылки на прямое соединение?
Где-то есть большая ошибка, и я надеюсь, что вы можете привести меня к правильномудорожка.Я ценю любую помощь, заранее спасибо