如何在MongoDb中启动事务



我试图阻止对特定记录的并发请求,请参阅以下示例:

function addMoney(orderID,orderID){
const status = Database.getOrder(orderID);
if (status === 1){
return "Money Already Added";
}
Database.udateOrder(orderID, {status: 1});
Database.addMoney(userID, 300);
return true;
}

假设有人恰好在同一时间提出了这个请求;"状态";检查通过后,他们将能够使Database.addMoney运行两次。

使用MySQL,我会启动一个transaction来锁定行,但不知道如何使用MongoDB来做到这一点。

您可以像MySQL一样在mongodb中执行事务。考虑使用具有id:123status:0order文档。然后,您可以检查交易中的状态,并在交易已付款或失败时返回,以便添加汇款单并更新订单状态。如果您遇到任何类似Transaction numbers are only allowed on a replica set member or mongos的问题,此链接可能会有所帮助。

为了使用事务,您需要一个MongoDB副本集,并且在本地启动一个副本集进行开发是一个复杂的过程。新的run-rs-npm模块使启动副本集变得容易。

const uri = 'mongodb://localhost:27017';
const dbName = 'myDB';
const MongoClient = require('mongodb').MongoClient;
async function main() {
const client = new MongoClient(uri);
await client.connect();
const session = client.startSession();
try {
await session.withTransaction(async () => {
const orders = client.db(dbName).collection('orders');
const money = client.db(dbName).collection('money');
let doc = await orders.findOne({orderID: 123});
if (doc && doc.status === 1) {
console.log("Money Already Added");
return
}
await orders.updateOne({orderID: 123}, {'$set': {status: 1}});
await money.insertOne({orderID: 123, userID: 100, amount: 300}, {session});
console.log("Money added");
});
await session.commitTransaction();
} catch (e) {
console.log(e);
} finally {
await session.endSession();
await client.close();
}
}
main()

上面的代码可能需要改进,因为我无法在带有副本集的MongoDB上进行测试

最新更新