Maison > Questions et réponses > le corps du texte
Je crée une classe utilitaire pour NodeJs pour m'aider à gérer les transactions de base de données.
Mon idée est de créer une méthode comme celle-ci :
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(); }) }
et utilisez-le comme ceci :
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(....) })
J'espérais que ça marcherait, mais apparemment le résultat est le suivant :
beginTransaction commit do query 1 do query 2 do query 3
Pensez-vous qu'il est possible de créer une fonction transactionBlock
返回一个承诺,用户可以在其中执行查询,最后,如果所有查询都正常,函数 transactionBlock
qui effectuera le commit ?
J'utilise ceci : npmjs.com/package/promise-mysql
Merci Au revoir
P粉5123632332024-03-31 10:11:13
Le gros problème avec votre approche actuelle est que finally()
toujours s'exécute indépendamment du fait que la chaîne de promesses soit résolue ou rejetée, vous ne voulez donc certainement pas y engager de transaction.
Je ne vois qu'une seule option ici... nécessite une fonction de rappel représentant le corps de la transaction.
En général, je recommande également d'utiliser la syntaxe async / wait
pour une meilleure lisibilité.
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)` } };
Appelle comme ça
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); }
Si vous utilisez Typescript, les interfaces et types suivants garantiront un fonctionnement fluide
type TxBody = (db: Connection) => Promise; type TransactionBlock = ( connectionName: string, txBody: TxBody ) => Promise ; const transactionBlock: TransactionBlock = async (connectionName, txBody) => { // ... };