suchen

Heim  >  Fragen und Antworten  >  Hauptteil

Der beste Weg, Transaktionen mit Promises effizient abzuwickeln

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粉226667290P粉226667290269 Tage vor510

Antworte allen(1)Ich werde antworten

  • P粉512363233

    P粉5123632332024-03-31 10:11:13

    您当前方法的大问题是 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) => {
      // ...
    };
    

    Antwort
    0
  • StornierenAntwort