我正在为 NodeJs 创建一个实用程序类来帮助我管理数据库事务。
我的想法是创建一个这样的方法:
transactionBlock(params) {
let _db;
return mySqlConnector.getConnection(params.db)
.then(db => {
_db = db;
console.log(`beginTransaction`);
return db.beginTransaction()
})
.then(() => {
return Promise.resolve(_db);
})
.catch((e) => {
console.log(`roolback`);
_db.rollback();
})
.finally(() => {
console.log(`commit`);
_db.commit();
})
}
并像这样使用它:
const params = {db:"my_db"};
transactionBlock(params)
.then(db =>{
console.log(`do query 1`);
db.insert(....)
console.log(`do query 2`);
db.insert(....)
console.log(`do query 3`);
db.insert(....)
})
我希望它能起作用,但显然结果如下:
beginTransaction commit do query 1 do query 2 do query 3
您认为是否可以创建一个函数 transactionBlock 返回一个承诺,用户可以在其中执行查询,最后,如果所有查询都正常,函数 transactionBlock 会执行提交?
我使用这个:npmjs.com/package/promise-mysql
谢谢 再见
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
您当前方法的大问题是
finally()始终 运行,无论承诺链解决还是拒绝,因此您绝对不想提交那里进行交易。我在这里只看到一个选项...需要一个代表交易主体的回调函数。
一般来说,我还建议使用
async / wait语法以提高可读性。const transactionBlock = async (connectionName, txBody) => { const db = await mySqlConnector.getConnection(connectionName); await db.beingTransaction(); try { await txBody(db); console.log("commit"); return db.commit(); // all good, commit } catch (err) { console.error("rollback", err); await db.rollback(); // keep the rejection chain going by re-throwing the error or a new one throw err; // or perhaps `new Error("DB error: " + err.message)` } };这样调用
try { await transactionBlock("my_db", async (db) => { console.log(`do query 1`); await db.insert(/* ... */); console.log(`do query 2`); await db.insert(/* ... */); console.log(`do query 3`); await db.insert(/* ... */); }); } catch (err) { console.error("oh no, something went wrong", err); }如果您使用 Typescript,以下接口和类型将确保顺利运行