【问题标题】:How to commit transaction after loop over asynchonous updates如何在异步更新循环后提交事务
【发布时间】:2013-08-14 15:53:48
【问题描述】:

我正在使用 node-mysql-queues 在我的应用程序中处理数据库事务。

for (lineitem in lineitems) {
        transaction.query("SELECT n from inventory WHERE productId = ?", [lineitem], function (err, rows) {
            if (err)
                transaction.rollback();
            var newN = rows[0].n - lineitems[lineitem].quantity;
            if (newN >= 0) {
                transaction.query("UPDATE inventory SET n = ? WHERE productId = ?", [newN, lineitem], function (err) {
                    if (err){
                        transaction.rollback();
                        console.log(err);
                    }
                    //here I want to commit if all updates were successfull!!!
                });
            }
        })
    }

正如您在代码中看到的,我不知道如何处理提交部分。如果是同步的就好了,但是不知道怎么解决这个问题。

感谢和问候

【问题讨论】:

    标签: node.js asynchronous transactions node-mysql


    【解决方案1】:

    使用async 模块之类的东西很容易。

    async.each(lineitems, performQuery, function(err) {
      if(err) {
        transaction.rollback();
        console.log(err);
        return;
      }
    
      transaction.commit();
    });
    
    function performQuery(lineitem, callback) {
      transaction.query("SELECT n from inventory WHERE productId = ?", [lineitem], function (err, rows) {
        if (err) return callback(err);
    
        var newN = rows[0].n - lineitems[lineitem].quantity;
        if (newN >= 0) {
          transaction.query("UPDATE inventory SET n = ? WHERE productId = ?", [newN, lineitem], function (err) {
            if (err) return callback(err);
    
            callback();
          });
        }
      });
    }
    

    【讨论】:

    • 嗨@Timothy,感谢您的提示。不幸的是我无法让它工作:(我在这里粘贴了我的代码(pastebin.com/quzkN3SN)并标记了我期望输出的行。此外我调试了应用程序。对于选择方法之后的回调,它指出:“函数不一致重新运行点”...还有什么想法吗?
    【解决方案2】:

    我找到了解决问题的方法。由于我在进行选择然后根据选择结果进行更新时遇到问题,因此我实现了条件更新之类的东西。 但是请看我的代码:

    mysql.getTransaction(function (err, transaction) {
        //For each item in the cart, call the performUpdate method
        //If an error occures, rollback the whole transaction
        async.each(lineitems, performUpdate, function (err) {
            if (err) {
                transaction.rollback();
                res.json(err.message);
                return;
            }
            //Since we are going to call another callback, we need to pause the transaction, else it would be committed automatically
            transaction.pause();
            //If the Updates were successfull, create an Order in MongoDB
            orderController.createMongoOrder(lineitems, req.session.cart.total, req.session.passport.user, function (err) {
                if (err) {
                    //If there is a Problem with Mongo, cancel the transaction
                    transaction.resume();
                    transaction.rollback();
                    res.json(err.message);
                } else {
                    //Else commit the transaction and empty the cart
                    transaction.resume();
                    transaction.commit();
                    req.session.cart = {
                        products: {},
                        count: 0,
                        total: 0
                    };
                    res.json("Order accepted!");
                }
            })
        });
    
        function performUpdate(lineitem, callback) {
            //This query can be seen as conditional update. If the number of articles in stock is not sufficient, there will be no affectedRows in the returned info message
            transaction.query("UPDATE inventory SET n = n -? WHERE productId = ? AND n >= ?", [lineitem.quantity, lineitem.id, lineitem.quantity],function (err, info) {
                if (err) {
                    return callback(err);
                } else {
                    //if for any item there is no affectedRow, this means the Updated failed. This should make the whole transaction roll back so we return an error to the callback
                    if (info.affectedRows != 1) {
                        return callback(new Error("Article: " + lineitem.productObject.name + " out of stock!"))
                    }
                    return callback(null, info);
                }
            }).execute()
        }
    })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多