我正在使用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!!!
});
}
})
}
正如您在代码中看到的,我不知道如何处理提交部分。如果它是同步的,那将很容易,但不知道如何解决这个问题。
谢谢&此致
答案 0 :(得分: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();
});
}
});
}
答案 1 :(得分:0)
我找到了解决问题的方法。由于我根据select的结果执行select然后更新时出现问题,因此我实现了类似条件更新的功能。 但请看我的代码:
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()
}
})