我正在使用猫鼬通过我的nodejs服务器连接到我的Mongodb Atlas集群。
有一个作为事务完成的特定操作。猫鼬需要mongoose.startSession()
才能开始交易。此mongoose.startSession()
调用很少会无限期挂起。没有确定的方法可以重现。
log.info('starting lock session');
const mongoSession = await mongoose.startSession();
log.info('lock session started');
在上面的代码中,starting lock session.
被记录下来,但是lock session started
在发生问题时没有被记录下来。
我将连接到数据库,如下所示:
const dburl = 'mongodb+srv://myuser:mypassword@myapp.mongodb.net/mydb?retryWrites=true&w=majority';
mongoose.connect(dburl, {useNewUrlParser: true}, err => {
if (err) {
log.warn('Error occurred when connecting to database. ' + err);
}
});
这可能是什么原因?这可能是由于数据库出现问题吗?有什么办法可以进一步解决此问题?
答案 0 :(得分:1)
这看起来像是猫鼬的错误,我向猫鼬报告了它,但仍然没有得到答复。
https://github.com/Automattic/mongoose/issues/8325
我编写了以下函数,可以用来等到猫鼬连接准备好后再调用startSession()
,这可以解决我的问题。
function waitForMongooseConnection(mongoose) {
return new Promise((resolve) => {
const connection = mongoose.connection;
if (connection.readyState === 1) {
resolve();
return;
}
console.log('Mongoose connection is not ready. Waiting for open or reconnect event.');
let resolved = false;
const setResolved = () => {
console.log('Mongoose connection became ready. promise already resolved: ' + resolved);
if (!resolved) {
console.log('Resolving waitForMongooseConnection');
resolved = true;
resolve();
}
};
connection.once('open', setResolved);
connection.once('reconnect', setResolved);
});
}
使用上述功能,我可以像下面这样开始会话:
log.info('starting session');
await waitForMongooseConnection(mongoose);
const mongoSession = await mongoose.startSession();
log.info('session started');
请注意,我必须关闭useUnifiedTopology
。否则,不会调用“重新连接”。
mongoose.connect(config.db, {useNewUrlParser: true, useUnifiedTopology: false}, err => {
if (err) {
log.warn('Error occurred when connecting to database. ' + err);
}
});
答案 1 :(得分:0)
我通过使用来自的 connection 对象解决了这个问题
mongoose.createConnection(uri, options)
const connection = mongoose.createConnection(uri, options);
const session = await connection.startSession();
session.startTransaction();
await MySchema.create({
value: "Created?",
session: session, // giving session here
});
await session.commitTransaction();
session.endSession();
<块引用>
mongoose.connection
与此连接对象不同。