0

アプリケーションでデータベース トランザクションを処理するために 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!!!
                });
            }
        })
    }

コードを見るとわかるように、コミット部分の処理方法がわかりません。同期であれば簡単ですが、この問題を解決する方法がわかりません。

ありがとうございます。それでは、お元気で

4

2 に答える 2

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();
      });
    }
  });
}
于 2013-08-14T21:12:12.367 に答える
0

問題の解決策を見つけました。選択してから選択の結果に応じて更新を行うのに問題があったため、条件付き更新のようなものを実装しました。しかし、私のコードを見てください:

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()
    }
})
于 2013-08-16T08:41:16.277 に答える