【问题标题】:How to start a transaction in MongoDb?如何在 MongoDb 中启动事务?
【发布时间】:2020-10-18 03:48:39
【问题描述】:

我正在尝试阻止对特定记录的并发请求,请参见以下示例:

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。

【问题讨论】:

    标签: node.js mongodb transactions


    【解决方案1】:

    您可以像 MySQL 一样在 mongodb 中执行事务。考虑拥有一个带有id:123status:0order 文档。然后您可以检查交易中的状态,如果它已经支付或失败则返回以添加货币文件并更新订单状态。 如果您遇到任何问题,例如 Transaction numbers are only allowed on a replica set member or mongos this link 可能会有所帮助。

    为了使用事务,您需要一个 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 上对其进行测试。

    【讨论】:

      猜你喜欢
      • 2011-06-23
      • 1970-01-01
      • 2011-06-30
      • 1970-01-01
      • 1970-01-01
      • 2017-08-11
      • 1970-01-01
      • 1970-01-01
      • 2015-08-03
      相关资源
      最近更新 更多