首页 > 解决方案 > mongodb 在 commitTransaction 失败后我需要 abortTransaction 吗?

问题描述

猫鼬/mongodb node.js 代码:

session.commitTransaction(function(err, reply){
    if(err) {
       session.abortTransaction(); //Do I need this abort?
    }
}

有没有人可以帮助我lz。

标签: mongodbmongoosetransactionscommitrollback

解决方案


查看有关事务的 mongodb文档及其提供的示例。

您应该session.abortTransaction();在数据库请求出现异常后使用。

commit但是拒绝后就不需要了。


那说猫鼬没有abortTransactions()。所以我想这不是必需的。


// Runs the txnFunc and retries if TransientTransactionError encountered

function runTransactionWithRetry(txnFunc, session) {
    while (true) {
        try {
            txnFunc(session);  // performs transaction
            break;
        } catch (error) {
            // If transient error, retry the whole transaction
            if ( error.hasOwnProperty("errorLabels") && error.errorLabels.includes("TransientTransactionError")  ) {
                print("TransientTransactionError, retrying transaction ...");
                continue;
            } else {
                throw error;
            }
        }
    }
}

// Retries commit if UnknownTransactionCommitResult encountered

function commitWithRetry(session) {
    while (true) {
        try {
            session.commitTransaction(); // Uses write concern set at transaction start.
            print("Transaction committed.");
            break;
        } catch (error) {
            // Can retry commit
            if (error.hasOwnProperty("errorLabels") && error.errorLabels.includes("UnknownTransactionCommitResult") ) {
                print("UnknownTransactionCommitResult, retrying commit operation ...");
                continue;
            } else {
                print("Error during commit ...");
                throw error;
            }
       }
    }
}

// Performs inserts and count in a transaction
function updateEmployeeInfo(session) {
   employeesCollection = session.getDatabase("hr").employees;
   eventsCollection = session.getDatabase("reporting").events;

   // Start a transaction for the session that uses:
   // - read concern "snapshot"
   // - write concern "majority"

   session.startTransaction( { readConcern: { level: "snapshot" }, writeConcern: { w: "majority" } } );

   try{
      eventsCollection.insertOne(
         { employee: 3, status: { new: "Active", old: null },  department: { new: "XYZ", old: null } }
      );

      // Count number of events for employee 3

      var countDoc = eventsCollection.aggregate( [ { $match:  { employee: 3 } }, { $count: "eventCounts" } ] ).next();

      print( "events count (in active transaction): " + countDoc.eventCounts );

      // The following operations should fail as an employee ``3`` already exist in employees collection
      employeesCollection.insertOne(
         { employee: 3, name: { title: "Miss", name: "Terri Bachs" }, status: "Active", department: "XYZ" }
      );
   } catch (error) {
      print("Caught exception during transaction, aborting.");
      session.abortTransaction();
      throw error;
   }

   commitWithRetry(session);

} // End of updateEmployeeInfo function

// Start a session.
session = db.getMongo().startSession( { mode: "primary" } );

try{
   runTransactionWithRetry(updateEmployeeInfo, session);
} catch (error) {
   // Do something with error
} finally {
   session.endSession();
}

推荐阅读