如何在MongoDb开始交易?
How to start a transaction in 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,我会开始一个事务来锁定行,但不确定如何使用 MongoDB。
您可以像 MySQL 一样在 mongodb 中进行交易。考虑使用 id:123
和 status:0
的 order
文档。然后,您可以检查交易状态和 return 是否已付款或失败,以便添加货币文件和更新订单状态。
如果您遇到任何类似 Transaction numbers are only allowed on a replica set member or mongos
的问题, 可能会有所帮助。
In order to use transactions, you need a MongoDB replica set, and
starting a replica set locally for development is an involved process.
The new run-rs npm module makes starting replica sets easy.
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 上使用副本集对其进行测试。
我试图阻止对特定记录的并发请求,请参见以下示例:
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,我会开始一个事务来锁定行,但不确定如何使用 MongoDB。
您可以像 MySQL 一样在 mongodb 中进行交易。考虑使用 id:123
和 status:0
的 order
文档。然后,您可以检查交易状态和 return 是否已付款或失败,以便添加货币文件和更新订单状态。
如果您遇到任何类似 Transaction numbers are only allowed on a replica set member or mongos
的问题,
In order to use transactions, you need a MongoDB replica set, and starting a replica set locally for development is an involved process. The new run-rs npm module makes starting replica sets easy.
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 上使用副本集对其进行测试。