【发布时间】:2020-08-20 17:06:51
【问题描述】:
我是第一次使用猫鼬交易。按照文档和一些文章,我能够使用 run-rs 来运行本地副本。但是,我遇到了两个问题,
- 即使事务反映在副本集上,mongoose 总是会抛出错误 MongoError: No transaction started。我已尝试检查解决方案,但找不到任何解决此问题的方法。
- 成功完成交易后,还有另一个异步函数用于发送通知电子邮件。然而,我意识到,不知何故,这个通知电子邮件功能在交易发生之前运行,然后交易功能运行第二。我猜这可能与承诺有关,如果我错了,请纠正我。
这是这两个函数的样子。
await transactionDb
.handleMoneyTransfer({
senderId,
receiverId: paymentInfo.getReceiver(),
amount: paymentInfo.getAmountToPay(),
ref
})
return await sendNotificationEmail({ ref, user })
handleMoneyTransfer 函数应该首先运行,然后sendNotificationEmail 应该在下一个运行,但这里不是这种情况。
这是处理下面列出的 mongoose 事务的代码。
async function handleMoneyTransfer({ senderId, receiverId, amount, ref }) {
const session = await mongoose.startSession()
try {
const sender = await User.findOne({ _id: senderId }).session(session)
sender.balance -= amount
await sender.save({ session })
const receiver = await User.findOne({ _id: receiverId }).session(session)
// receiver.balance += amount
const transactionInfo = await Transaction.findOne({
reference: ref
}).session(session)
const newEscrow = await new Escrow({
amount,
reference: ref,
buyerInfo: {
buyerId: sender._id,
email: sender.email
},
sellerInfo: {
sellerId: receiverId,
email: receiver.email
},
currentTransaction: {
transaction: transactionInfo
}
})
await newEscrow.save({ session })
await session.commitTransaction()
} catch (error) {
await session.abortTransaction()
} finally {
session.endSession()
}
}
这是我使用猫鼬连接的方式
const setupDB = async (uri, dbUrl) => {
try {
await mongoose.connect(`${uri}/${dbUrl}`, {
useUnifiedTopology: true,
useNewUrlParser: true,
replicaSet: 'rs'
})
console.log('Connected')
} catch (e) {
return console.log(e)
}
}
翻译成这个
setupDB(
'mongodb://DESKTOP-SNA1HQK:27017,DESKTOP-SNA1HQK:27018,DESKTOP-SNA1HQK:27019',
'escrow?replicaSet=rs'
)
现在,我一直在修复 No transaction started 错误并让这些函数按照它们的放置顺序运行。
非常感谢您的帮助,在此先感谢您。
【问题讨论】:
标签: javascript node.js mongodb express mongoose