我正在為 mysql 使用節點的驅動程式,并且需要一個接一個地執行“n”個事務,而不是同時執行。
我試過使用 for/forEach 回圈,但事務似乎同時發生,這導致我的 api 崩潰。這是錯誤:-
throw err; // Rethrow non-MySQL errors
^
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
一筆交易似乎作業得很好。
每個事務有 4 個查詢,req.body 是一個物件陣列:-
router.post('/production/add', (req, res) => {
for (const obj of req.body) {
pool.getConnection(function (err, connection) {
connection.beginTransaction(function (err) {
if (err) throw err;
const query1 = `select qty from production where prc_id = ${obj.prc_id}`;
console.log(query1);
connection.query(query1, function (error, result1, fields) {
if (error) {
return connection.rollback(function () {
res.status(400).send({ query: 1, message: error.sqlMessage, code: error.code, errno: error.errno });
return;
});
}
const new_prod_qty = result1[0].qty - obj.auth_prod_qty;
const query2 = new_prod_qty > 0 ? `update production set qty = ${new_prod_qty} where prc_id = ${obj.prc_id}` : `delete from production where prc_id = ${obj.prc_id}`;
console.log(query2);
connection.query(query2, function (error, results2, fields) {
if (error) {
return connection.rollback(function () {
res.status(400).send({ message: error.sqlMessage, code: error.code, errno: error.errno });
return;
});
}
const query3 = `update prc set auth_prod_qty = ${obj.auth_prod_qty} where prc_id = ${obj.prc_id}`;
console.log(query3);
connection.query(query3, function (error, results3, fields) {
if (error) {
return connection.rollback(function () {
res.status(400).send({ message: error.sqlMessage, code: error.code, errno: error.errno });
return;
});
}
const query4 = "select * from store";
connection.query(query4, function (error, results3, fields) {
if (error) {
return connection.rollback(function () {
res.status(400).send({ message: error.sqlMessage, code: error.code, errno: error.errno });
return;
});
}
connection.commit(function (err) {
if (err) {
return connection.rollback(function () {
res.status(400).send({ message: error.sqlMessage, code: error.code, errno: error.errno });
return;
});
}
res.status(201).send(results2);
});
});
});
});
});
});
});
};
});
根據一些研究,Sequelize ORM 似乎承諾交易,但我希望將其用作最后的手段。任何有或沒有 Sequelize 的解決方案都將不勝感激!
提前致謝!
解決方案:-
router.post('/stock/add', async (req, res) => {
const connection = pool.getConnection(async function (err, connection) {
if (err) {
connection.release();
res.status(400).send(err);
return;
}
else {
for (const obj of req.body) {
try {
await connection.promise().beginTransaction();
const [result1, fields1] = await connection.promise().query(query1)
const [result2, fields2] = await connection.promise().query(query2);
const [result3, fields3] = await connection.promise().query(query3);
const [result4, fields4] = await connection.promise().query(query4);
await connection.promise().commit();
}
catch (error) {
await connection.promise().rollback();
connection.release();
res.status(400).send(error);
return;
}
}
res.status(200).send('Transaction Complete');
}
});
});
uj5u.com熱心網友回復:
您需要使用async / await來按順序運行您的 txs。這該怎么做?
使用npm mysql2代替npm mysql。這讓你promisified(awaitable)版本的API時的你require('mysql2/promise')。另外,這是很多更有趣的編程和除錯比那些可憐的嵌套回呼。只是不要忘記awaits。
將此基本大綱用于代碼的資料處理回圈。一切都會按順序進行。創建池的方式略有不同;閱讀 npm 頁面。這個沒有除錯。
const mysql = require('mysql2/promise');
router.post('/production/add', async (req, res) => {
const connection = await pool.getConnection()
for (const obj of req.body) {
try {
await connection.beginTransaction()
const query1 = 'whatever'
const result1 = await connection.query(query1)
const query2 = 'something else'
const result 2 = await connection.query(query2)
/* etcetera etcetera */
await connection.commit()
}
catch (error) {
await connection.rollback()
pool.releaseConnection()
res.status(400).send({ something })
}
}
pool.releaseConnection()
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/374074.html
標籤:mysql 节点.js 表达 交易 sequelize.js
上一篇:在函式記憶體根特定的API請求
