Gau*_*ar 11 transactions acid mongoose mongodb node.js
我正在开发一个应用程序,我在应用程序层使用MongoDB作为数据库和Nodejs + Express,我有两个集合,即
在这里,我必须更新成千上万用户的钱包,如果成功创建一个新文档,每个交易的相关信息,这是我的代码:
userModel.update({_id : ObjectId(userId)}, {$inc : {wallet : 500}}, function (err, creditInfo) {
if(err){
console.log(err);
}
if(creditInfo.nModified > 0) {
newTransModel = new transModel({
usersId: ObjectId(userId),
amount: winAmt,
type: 'credit',
});
newTransModel.save(function (err, doc) {
if(err){
Cb(err);
}
});
}
});
Run Code Online (Sandbox Code Playgroud)
但是这个解决方案并不atomic总是有可能用金额更新用户钱包,但是在交易收集中没有创建相关交易导致经济损失.
我听说最近MongoDB已经添加Transactions了对它的支持4.0 version,我已经阅读了MongoDB文档但是无法用Node.js中的mongoose成功实现它,有人能告诉我如何使用TransactionsMongoDB 的最新功能重新实现上面的代码哪些有这些功能
Session.startTransaction()
Session.abortTransaction()
Session.commitTransaction()
Run Code Online (Sandbox Code Playgroud)
MongoDB文档:点击这里
Wan*_*iar 16
在Node.js中使用mongoose,任何人都可以告诉我如何使用最新的事务功能重新实现上面的代码
要在mongoose中使用MongoDB多文档事务支持,您需要大于v5.2的版本.例如:
npm install mongoose@5.2
Run Code Online (Sandbox Code Playgroud)
Mongoose事务方法返回一个promise而不是一个需要使用的session await.看到:
例如,在上面的资源和示例中更改示例,您可以尝试:
const User = mongoose.model('Users', new mongoose.Schema({
userId: String, wallet: Number
}));
const Transaction = mongoose.model('Transactions', new mongoose.Schema({
userId: ObjectId, amount: Number, type: String
}));
await updateWallet(userId, 500);
async function updateWallet(userId, amount) {
const session = await User.startSession();
session.startTransaction();
try {
const opts = { session };
const A = await User.findOneAndUpdate(
{ _id: userId }, { $inc: { wallet: amount } }, opts);
const B = await Transaction(
{ usersId: userId, amount: amount, type: "credit" })
.save(opts);
await session.commitTransaction();
session.endSession();
return true;
} catch (error) {
// If an error occurred, abort the whole transaction and
// undo any changes that might have happened
await session.abortTransaction();
session.endSession();
throw error;
}
}
Run Code Online (Sandbox Code Playgroud)
不是原子的,总是有可能用金额更新用户钱包,但是在交易集合中没有创建相关交易导致经济损失
您还应该考虑更改MongoDB 数据模型.特别是如果这两个系列是自然联系的.有关更多信息,另请参阅原子操作的模型数据.
您可以尝试的示例模型是Event Sourcing模型.首先创建一个事务条目作为事件,然后使用聚合重新计算用户的钱包余额.
例如:
{tranId: 1001, fromUser:800, toUser:99, amount:300, time: Date(..)}
{tranId: 1002, fromUser:77, toUser:99, amount:100, time: Date(..)}
Run Code Online (Sandbox Code Playgroud)
然后根据需求(即每6小时)引入一个过程来计算每个用户每个用户的数量作为缓存.您可以通过添加以下内容来显示当前用户的钱包余额:
| 归档时间: |
|
| 查看次数: |
10266 次 |
| 最近记录: |