mongodb мне нужно abortTransaction после неудачной фиксации транзакции - PullRequest
0 голосов
/ 30 августа 2018

mongoose / mongodb node.js код:

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

Есть ли кто-нибудь, кто может помочь мне, плз.

Ответы [ 2 ]

0 голосов
/ 20 июня 2019

Старая тема, но предполагается, что она даст некоторые новички.

На примере MongoDB для повторной транзакции и фиксации операции после session.commitTransaction().

они вызывают session.abortTransaction().
try {
    await commitWithRetry(session);
} catch (error) {
    await session.abortTransaction();
    throw error;
}

Что вступает в конфликт со спецификацией abortTransaction MongoDB , которая гласит следующее:

Это верно только для вызова abortTransaction, когда сеанс находится в состояние «начальная транзакция» или «транзакция в процессе».

Если этот сеанс находится в состоянии «транзакция зафиксирована», то драйверы ДОЛЖЕН поднять ошибку, содержащую сообщение «Невозможно позвонить» abortTransaction после вызова commitTransaction ".

Когда сеанс находится в состоянии «начальная транзакция», то есть нет Для этой транзакции были выполнены операции, драйверы НЕ ДОЛЖНЫ выполните команду abortTransaction.

Так что я думаю, что ответ на ваш вопрос, вы не должны. В противном случае вы получите ошибку: Cannot call abortTransaction after calling commitTransaction.

0 голосов
/ 30 августа 2018

Просмотр документации 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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...