我正在尝试为mongodb中的多个数据库连接实现一个事务。但这卡在startSession()中。我有两个db(副本集),每个都有两个连接。
var express = require('express');
var router = express.Router();
const mongoose = require('mongoose');
//set replica set
const options = { replicaSet: 'replocal', useNewUrlParser: true, };
// create connection from diffrent db
var conn = mongoose.createConnection('mongodb://localhost:27017/db1', options);
var conn2 = mongoose.createConnection('mongodb://localhost:27017/db2', options);
// create account in diffent db
const AccountFromdb1 = conn.model('AccountFromdb1', new mongoose.Schema({ name: String, balance: Number }));
const AccountFromdb2 = conn2.model('AccountFromdb2', new mongoose.Schema({ name: String, balance: Number }));
/* transaction test */
router.get('/transaction', async function (req, res, next) {
// Insert accounts and transfer some money
await AccountFromdb1.create({ name: 'A', balance: 5 });
await AccountFromdb2.create({ name: 'B', balance: 10 });
//start session
const session = await mongoose.startSession(); // <--- stuck here
session.startTransaction();
try {
const opts = { session, new: true };
const A = await AccountFromdb1.
findOneAndUpdate({ name: 'A' }, { $inc: { balance: -5 } }, opts);
if (A.balance < 0) {
throw new Error('Insufficient funds: ' + (A.balance + 5));
}
await AccountFromdb2.
findOneAndUpdate({ name: 'B' }, { $inc: { balance: 5 } }, opts);
await session.commitTransaction();
session.endSession();
next();
} catch (error) {
// If an error occurred, abort the whole transaction.
await session.abortTransaction();
session.endSession();
throw error;
}
});
module.exports = router;
关于MongoDB文档形式的交易:
您可以在现有集合上指定读/写(CRUD)操作。 集合可以位于不同的数据库ref
中
答案 0 :(得分:1)
两个数据库都必须位于同一mongodb群集上,才能正常工作。所以代替这个
var conn = mongoose.createConnection('mongodb://localhost:27017/db1', options);
var conn2 = mongoose.createConnection('mongodb://localhost:27017/db2', options);
使用猫鼬Connection.useDB()
方法https://mongoosejs.com/docs/api/connection.html#connection_Connection-useDb。这样,猫鼬将为两个连接使用相同的连接池。像这样:
let con1 = mongoose.createConnection('mongodb://localhost:27017/db1', options);
let con2 = con1.useDb("db2")
现在假设您有2个模型,其中db1的模型1和db2的模型2
然后您可以创建一个可以在两个数据库上工作的事务,像这样
let session = await con1.startSession()
session.startTransaction();
try {
// First db
let result1 = await new Model1({...something}).save()
// Second db
let result2 = await new Model2({...something}).save()
await session.commitTransaction()
} catch (err) {
await session.abortTransaction()
throw err
}finally {
session.endSession();
}
有关更多信息,请在此处查看NodeJS示例:https://docs.mongodb.com/manual/core/transactions-in-applications/