Knex 正在返回检测到死锁
Knex is returning Deadlock Detected
所以我有这个函数可以减少数据库中的库存,问题是,如果我必须减去 2 个不同项目的数量,Knex 将返回 'Deadlock Detected',因此代码循环。
const updateOrder = (req, res, db, logger) => {
let {
status,
trx_id,
orNumber,
returnReason
} = req.body;
db.transaction((trx) => {
db('cart')
.returning('*')
.where('trx_id', '=', trx_id)
.update({
status: status,
or_num: orNumber,
return_reason: returnReason
})
.then(order => {
if (status === 'Success') {
db('cart')
.returning('*')
.where('trx_id', '=', trx_id)
.update({
date_purchased: new Date()
})
.then(purchased => {
db.transaction((trx) => {
db.select('*').from('cart_item').where({
cart_id: order[0].id,
trx_id: order[0].trx_id
})
.then(item => {
let newQuantity = [];
if (item[0]) {
for (let i = 0; i < item.length; i++) {
db.select('*').from('product').where('item_code', '=', item[i].item_code)
.then(product => {
for (let ii = 0; ii < product.length; ii++) {
if (product[ii]) {
newQuantity[ii] = parseInt(product[ii].stock) - parseInt(item[i].quantity)
db('product')
.returning('*')
.where('item_code', '=', item[i].item_code)
.update({
stock: newQuantity[ii]
})
.then(stock => {
if (stock[0]) {
db('activity_order_logs')
.returning('*')
.insert({
date: new Date(),
employee_id: req.session.emp_id,
module: "MONITORING",
trx_id: trx_id,
activity: status,
or_num: orNumber
})
.then(activity => {
if (activity[0]) {
res.json({
isSuccess: true
});
return;
} else {
res.json({
isSuccess: false
});
return;
}
})
.then(trx.commit)
.catch(err => {
logger.error(err);
trx.rollback;
res.render('pages/error-500');
});
}
})
.then(trx.commit)
.catch(err => {
logger.error(err);
trx.rollback;
res.render('pages/error-500');
});
}
}
})
.then(trx.commit)
.catch(err => {
logger.error(err);
trx.rollback;
res.render('pages/error-500');
});
}
}
})
.then(trx.commit)
.catch(err => {
logger.error(err);
trx.rollback;
res.render('pages/error-500');
});
})
.catch(err => logger.error(err));
})
.catch(err => logger.error(err));
} else if (status === 'Returned'){
if (order[0]) {
db('activity_order_logs')
.returning('*')
.insert({
date: new Date(),
employee_id: req.session.emp_id,
module: "MONITORING",
trx_id: trx_id,
activity: status,
or_num: orNumber,
return_reason: returnReason
})
.then(activity => {
if (activity[0]) {
res.json({
isSuccess: true
});
return;
} else {
res.json({
isSuccess: false
});
return;
}
})
.then(trx.commit)
.catch(err => {
logger.error(err);
trx.rollback;
res.render('pages/error-500');
});
}
}
else {
if (order[0]) {
db('activity_order_logs')
.returning('*')
.insert({
date: new Date(),
employee_id: req.session.emp_id,
module: "MONITORING",
trx_id: trx_id,
activity: status,
or_num: orNumber
})
.then(activity => {
if (activity[0]) {
res.json({
isSuccess: true
});
return;
} else {
res.json({
isSuccess: false
});
return;
}
})
.then(trx.commit)
.catch(err => {
logger.error(err);
trx.rollback;
res.render('pages/error-500');
});
}
}
})
.then(trx.commit)
.catch(err => {
logger.error(err);
trx.rollback;
res.render('pages/error-500');
});
})
.catch(err => logger.error(err));
}
module.exports = {
updateOrder
}
我是 NodeJS 的新手,我知道我的代码中有一个 promise 地狱,因为我不能实现 promise,因为我必须将前一个 promise 的数据用于下一个 promise。
如果我只需要使用一个更新查询,代码工作正常,但当我必须使用两个时遇到死锁。
您应该从学习如何使用 promises
和 async/await
开始,然后用它们做一些更简单的事情。处理 promise 的错误太多了,我数不清了。实际上,您正在并行执行大量操作,而无需等待较早的查询准备就绪。
Knex is returning Deadlock Detected
意味着您以一种他们正在锁定彼此执行的方式并发地对数据库进行了查询。
在多方研究的帮助下,我终于摆脱了死锁错误,同时对代码进行了扁平化处理。
这是工作代码:
const updateOrder = (req, res, db, logger) => {
let {
status,
trx_id,
orNumber,
returnReason
} = req.body;
const updateStatus = () => {
return db('cart')
.returning('*')
.where('trx_id', '=', trx_id)
.update({
status: status,
or_num: orNumber,
return_reason: returnReason
});
}
const updateDate = () => {
return db('cart')
.returning('*')
.where('trx_id', '=', trx_id)
.update({
date_purchased: new Date()
});
}
const selectItems = (order) => {
return db
.select('*')
.from('cart_items')
.where({
cart_id: order.id,
trx_id: order.trx_id
});
}
const selectProduct = (item) => {
const queries = [];
item.forEach(item => {
const query = db.select('*')
.from('product')
.where('item_code', '=', item.item_code);
queries.push(query);
})
return Promise.all(queries);
}
const updateQuantity = (product, cart) => {
const prodQuantity = product.map(product => parseInt(product.stock));
const cartQuantity = cart.map(cart => parseInt(cart.quantity));
const newQuantity = [];
const queries = [];
for(let i = 0; i < product.length; i++){
newQuantity.push(prodQuantity[i] - cartQuantity[i]);
}
cart.map((cart, index) => {
const query = db('products')
.returning('*')
.where('item_code', '=', cart.item_code)
.update({
stock: newQuantity[index]
})
queries.push(query);
})
return queries;
}
const updateLogs = () => {
return db('activity_order_logs')
.returning('*')
.insert({
date: new Date(),
employee_id: req.session.emp_id,
module: "MONITORING",
trx_id: trx_id,
activity: status,
or_num: orNumber
})
}
const sendResponse = (result) => {
if (result) {
res.json({
isSuccess: true
});
return;
} else {
res.json({
isSuccess: false
});
return;
}
}
(async () => {
const first = await updateStatus();
// console.log(first);
if(first[0].status == 'Success'){
const second = await updateDate().catch(err => {
throw err
});
// console.log(second);
const third = await selectItems(second[0]).catch(err => {
throw err
});
// console.log(third);
const fourth = await selectProduct(third).catch(err => {
throw err
});
const fourth2 = [].concat(...fourth);
// console.log(fourth2);
const fifth = await updateQuantity(fourth2, third)
const decreaseStock = async () => {
const finalResult = [];
for (let i = 0; i < fifth.length; i++) {
const finalQuery = await Promise.resolve(fifth[i]);
finalResult.push(finalQuery);
}
return finalResult;
};
const result = await decreaseStock().catch(err => {
throw err
});
const result2 = [].concat(...result);
const logs = await updateLogs().catch(err => {
throw err
});
const sendRes = await sendResponse(logs);
} else if(first[0].status == 'Returned'){
const logs = await updateLogs().catch(err => {
throw err
});
const sendRes = await sendResponse(logs);
} else {
const logs = await updateLogs().catch(err => {
throw err
});
const sendRes = await sendResponse(logs);
}
})().catch(err => {
console.log(err);
res.json({ isSuccess: false })
});
}
module.exports = {
updateOrder
}
我有一个新问题,特别是与交易有关的问题,但会 post 将它变成另一个问题。
所以我有这个函数可以减少数据库中的库存,问题是,如果我必须减去 2 个不同项目的数量,Knex 将返回 'Deadlock Detected',因此代码循环。
const updateOrder = (req, res, db, logger) => {
let {
status,
trx_id,
orNumber,
returnReason
} = req.body;
db.transaction((trx) => {
db('cart')
.returning('*')
.where('trx_id', '=', trx_id)
.update({
status: status,
or_num: orNumber,
return_reason: returnReason
})
.then(order => {
if (status === 'Success') {
db('cart')
.returning('*')
.where('trx_id', '=', trx_id)
.update({
date_purchased: new Date()
})
.then(purchased => {
db.transaction((trx) => {
db.select('*').from('cart_item').where({
cart_id: order[0].id,
trx_id: order[0].trx_id
})
.then(item => {
let newQuantity = [];
if (item[0]) {
for (let i = 0; i < item.length; i++) {
db.select('*').from('product').where('item_code', '=', item[i].item_code)
.then(product => {
for (let ii = 0; ii < product.length; ii++) {
if (product[ii]) {
newQuantity[ii] = parseInt(product[ii].stock) - parseInt(item[i].quantity)
db('product')
.returning('*')
.where('item_code', '=', item[i].item_code)
.update({
stock: newQuantity[ii]
})
.then(stock => {
if (stock[0]) {
db('activity_order_logs')
.returning('*')
.insert({
date: new Date(),
employee_id: req.session.emp_id,
module: "MONITORING",
trx_id: trx_id,
activity: status,
or_num: orNumber
})
.then(activity => {
if (activity[0]) {
res.json({
isSuccess: true
});
return;
} else {
res.json({
isSuccess: false
});
return;
}
})
.then(trx.commit)
.catch(err => {
logger.error(err);
trx.rollback;
res.render('pages/error-500');
});
}
})
.then(trx.commit)
.catch(err => {
logger.error(err);
trx.rollback;
res.render('pages/error-500');
});
}
}
})
.then(trx.commit)
.catch(err => {
logger.error(err);
trx.rollback;
res.render('pages/error-500');
});
}
}
})
.then(trx.commit)
.catch(err => {
logger.error(err);
trx.rollback;
res.render('pages/error-500');
});
})
.catch(err => logger.error(err));
})
.catch(err => logger.error(err));
} else if (status === 'Returned'){
if (order[0]) {
db('activity_order_logs')
.returning('*')
.insert({
date: new Date(),
employee_id: req.session.emp_id,
module: "MONITORING",
trx_id: trx_id,
activity: status,
or_num: orNumber,
return_reason: returnReason
})
.then(activity => {
if (activity[0]) {
res.json({
isSuccess: true
});
return;
} else {
res.json({
isSuccess: false
});
return;
}
})
.then(trx.commit)
.catch(err => {
logger.error(err);
trx.rollback;
res.render('pages/error-500');
});
}
}
else {
if (order[0]) {
db('activity_order_logs')
.returning('*')
.insert({
date: new Date(),
employee_id: req.session.emp_id,
module: "MONITORING",
trx_id: trx_id,
activity: status,
or_num: orNumber
})
.then(activity => {
if (activity[0]) {
res.json({
isSuccess: true
});
return;
} else {
res.json({
isSuccess: false
});
return;
}
})
.then(trx.commit)
.catch(err => {
logger.error(err);
trx.rollback;
res.render('pages/error-500');
});
}
}
})
.then(trx.commit)
.catch(err => {
logger.error(err);
trx.rollback;
res.render('pages/error-500');
});
})
.catch(err => logger.error(err));
}
module.exports = {
updateOrder
}
我是 NodeJS 的新手,我知道我的代码中有一个 promise 地狱,因为我不能实现 promise,因为我必须将前一个 promise 的数据用于下一个 promise。
如果我只需要使用一个更新查询,代码工作正常,但当我必须使用两个时遇到死锁。
您应该从学习如何使用 promises
和 async/await
开始,然后用它们做一些更简单的事情。处理 promise 的错误太多了,我数不清了。实际上,您正在并行执行大量操作,而无需等待较早的查询准备就绪。
Knex is returning Deadlock Detected
意味着您以一种他们正在锁定彼此执行的方式并发地对数据库进行了查询。
在多方研究的帮助下,我终于摆脱了死锁错误,同时对代码进行了扁平化处理。
这是工作代码:
const updateOrder = (req, res, db, logger) => {
let {
status,
trx_id,
orNumber,
returnReason
} = req.body;
const updateStatus = () => {
return db('cart')
.returning('*')
.where('trx_id', '=', trx_id)
.update({
status: status,
or_num: orNumber,
return_reason: returnReason
});
}
const updateDate = () => {
return db('cart')
.returning('*')
.where('trx_id', '=', trx_id)
.update({
date_purchased: new Date()
});
}
const selectItems = (order) => {
return db
.select('*')
.from('cart_items')
.where({
cart_id: order.id,
trx_id: order.trx_id
});
}
const selectProduct = (item) => {
const queries = [];
item.forEach(item => {
const query = db.select('*')
.from('product')
.where('item_code', '=', item.item_code);
queries.push(query);
})
return Promise.all(queries);
}
const updateQuantity = (product, cart) => {
const prodQuantity = product.map(product => parseInt(product.stock));
const cartQuantity = cart.map(cart => parseInt(cart.quantity));
const newQuantity = [];
const queries = [];
for(let i = 0; i < product.length; i++){
newQuantity.push(prodQuantity[i] - cartQuantity[i]);
}
cart.map((cart, index) => {
const query = db('products')
.returning('*')
.where('item_code', '=', cart.item_code)
.update({
stock: newQuantity[index]
})
queries.push(query);
})
return queries;
}
const updateLogs = () => {
return db('activity_order_logs')
.returning('*')
.insert({
date: new Date(),
employee_id: req.session.emp_id,
module: "MONITORING",
trx_id: trx_id,
activity: status,
or_num: orNumber
})
}
const sendResponse = (result) => {
if (result) {
res.json({
isSuccess: true
});
return;
} else {
res.json({
isSuccess: false
});
return;
}
}
(async () => {
const first = await updateStatus();
// console.log(first);
if(first[0].status == 'Success'){
const second = await updateDate().catch(err => {
throw err
});
// console.log(second);
const third = await selectItems(second[0]).catch(err => {
throw err
});
// console.log(third);
const fourth = await selectProduct(third).catch(err => {
throw err
});
const fourth2 = [].concat(...fourth);
// console.log(fourth2);
const fifth = await updateQuantity(fourth2, third)
const decreaseStock = async () => {
const finalResult = [];
for (let i = 0; i < fifth.length; i++) {
const finalQuery = await Promise.resolve(fifth[i]);
finalResult.push(finalQuery);
}
return finalResult;
};
const result = await decreaseStock().catch(err => {
throw err
});
const result2 = [].concat(...result);
const logs = await updateLogs().catch(err => {
throw err
});
const sendRes = await sendResponse(logs);
} else if(first[0].status == 'Returned'){
const logs = await updateLogs().catch(err => {
throw err
});
const sendRes = await sendResponse(logs);
} else {
const logs = await updateLogs().catch(err => {
throw err
});
const sendRes = await sendResponse(logs);
}
})().catch(err => {
console.log(err);
res.json({ isSuccess: false })
});
}
module.exports = {
updateOrder
}
我有一个新问题,特别是与交易有关的问题,但会 post 将它变成另一个问题。