Der beste Weg, Transaktionen mit Promises effizient abzuwickeln
P粉226667290
P粉226667290 2024-03-30 20:44:23
0
1
497

Ich erstelle eine Hilfsklasse für NodeJs, die mir bei der Verwaltung von Datenbanktransaktionen hilft.

Meine Idee ist, eine Methode wie diese zu erstellen:

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();
        })
}

und verwenden Sie es so:

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(....)
    })

Ich hatte gehofft, dass es funktionieren würde, aber anscheinend ist das Ergebnis dieses:

beginTransaction
commit
do query 1
do query 2
do query 3

Glauben Sie, dass es möglich ist, eine Funktion transactionBlock 返回一个承诺,用户可以在其中执行查询,最后,如果所有查询都正常,函数 transactionBlock zu erstellen, die den Commit durchführt?

Ich verwende Folgendes: npmjs.com/package/promise-mysql

Vielen Dank Auf Wiedersehen

P粉226667290
P粉226667290

Antworte allen(1)
P粉512363233

您当前方法的大问题是 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,以下接口和类型将确保顺利运行

type TxBody = (db: Connection) => Promise;
type TransactionBlock = (
  connectionName: string,
  txBody: TxBody
) => Promise;

const transactionBlock: TransactionBlock = async (connectionName, txBody) => {
  // ...
};
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage