diff options
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/db/commands/txn_cmds.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/kill_sessions_local.cpp | 74 | ||||
-rw-r--r-- | src/mongo/db/ops/write_ops_exec.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/repl/transaction_oplog_application.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/s/txn_two_phase_commit_cmds.cpp | 7 | ||||
-rw-r--r-- | src/mongo/db/service_entry_point_common.cpp | 30 | ||||
-rw-r--r-- | src/mongo/db/session_catalog_mongod.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/transaction_metrics_observer.cpp | 11 | ||||
-rw-r--r-- | src/mongo/db/transaction_participant.cpp | 90 | ||||
-rw-r--r-- | src/mongo/db/transaction_participant.h | 39 | ||||
-rw-r--r-- | src/mongo/db/transaction_participant_test.cpp | 209 | ||||
-rw-r--r-- | src/mongo/dbtests/storage_timestamp_tests.cpp | 4 |
12 files changed, 168 insertions, 304 deletions
diff --git a/src/mongo/db/commands/txn_cmds.cpp b/src/mongo/db/commands/txn_cmds.cpp index ecb756b67d6..8a0fe30e9ec 100644 --- a/src/mongo/db/commands/txn_cmds.cpp +++ b/src/mongo/db/commands/txn_cmds.cpp @@ -196,7 +196,7 @@ public: opCtx, *opCtx->getLogicalSessionId(), *opCtx->getTxnNumber()); } - txnParticipant.abortActiveTransaction(opCtx); + txnParticipant.abortTransaction(opCtx); if (MONGO_FAIL_POINT(participantReturnNetworkErrorForAbortAfterExecutingAbortLogic)) { uasserted(ErrorCodes::HostUnreachable, diff --git a/src/mongo/db/kill_sessions_local.cpp b/src/mongo/db/kill_sessions_local.cpp index 0e5c13a964d..8a7db69f64c 100644 --- a/src/mongo/db/kill_sessions_local.cpp +++ b/src/mongo/db/kill_sessions_local.cpp @@ -86,17 +86,21 @@ void killSessionsAction( void killSessionsAbortUnpreparedTransactions(OperationContext* opCtx, const SessionKiller::Matcher& matcher, ErrorCodes::Error reason) { - killSessionsAction( - opCtx, - matcher, - [](const ObservableSession& session) { - auto participant = TransactionParticipant::get(session); - return participant.transactionIsOpen() && !participant.transactionIsPrepared(); - }, - [](OperationContext* opCtx, const SessionToKill& session) { - TransactionParticipant::get(session).abortTransactionIfNotPrepared(opCtx); - }, - reason); + killSessionsAction(opCtx, + matcher, + [](const ObservableSession& session) { + auto participant = TransactionParticipant::get(session); + return participant.transactionIsInProgress(); + }, + [](OperationContext* opCtx, const SessionToKill& session) { + auto participant = TransactionParticipant::get(session); + // This is the same test as in the filter, but we must check again now + // that the session is checked out. + if (participant.transactionIsInProgress()) { + participant.abortTransaction(opCtx); + } + }, + reason); } SessionKiller::Result killSessionsLocal(OperationContext* opCtx, @@ -114,22 +118,31 @@ SessionKiller::Result killSessionsLocal(OperationContext* opCtx, void killAllExpiredTransactions(OperationContext* opCtx) { SessionKiller::Matcher matcherAllSessions( KillAllSessionsByPatternSet{makeKillAllSessionsByPattern(opCtx)}); - killSessionsAction( - opCtx, - matcherAllSessions, - [when = opCtx->getServiceContext()->getPreciseClockSource()->now()]( - const ObservableSession& session) { - return TransactionParticipant::get(session).expiredAsOf(when); - }, - [](OperationContext* opCtx, const SessionToKill& session) { - auto txnParticipant = TransactionParticipant::get(session); - log() - << "Aborting transaction with txnNumber " << txnParticipant.getActiveTxnNumber() - << " on session " << session.getSessionId().getId() - << " because it has been running for longer than 'transactionLifetimeLimitSeconds'"; - txnParticipant.abortTransactionIfNotPrepared(opCtx); - }, - ErrorCodes::ExceededTimeLimit); + killSessionsAction(opCtx, + matcherAllSessions, + [when = opCtx->getServiceContext()->getPreciseClockSource()->now()]( + const ObservableSession& session) { + return TransactionParticipant::get(session).expiredAsOf(when); + }, + [](OperationContext* opCtx, const SessionToKill& session) { + auto txnParticipant = TransactionParticipant::get(session); + // If the transaction is aborted here, it means it was aborted after + // the filter. The most likely reason for this is that the transaction + // was active and the session kill aborted it. We still want to log + // that as aborted due to transactionLifetimeLimitSessions. + if (txnParticipant.transactionIsInProgress() || + txnParticipant.transactionIsAborted()) { + log() << "Aborting transaction with txnNumber " + << txnParticipant.getActiveTxnNumber() << " on session " + << session.getSessionId().getId() + << " because it has been running for longer than " + "'transactionLifetimeLimitSeconds'"; + if (txnParticipant.transactionIsInProgress()) { + txnParticipant.abortTransaction(opCtx); + } + } + }, + ErrorCodes::ExceededTimeLimit); } void killSessionsLocalShutdownAllTransactions(OperationContext* opCtx) { @@ -156,10 +169,13 @@ void killSessionsAbortAllPreparedTransactions(OperationContext* opCtx) { return TransactionParticipant::get(session).transactionIsPrepared(); }, [](OperationContext* opCtx, const SessionToKill& session) { + // We're holding the RSTL, so the transaction shouldn't be otherwise + // affected. + invariant(TransactionParticipant::get(session).transactionIsPrepared()); // Abort the prepared transaction and invalidate the session it is // associated with. - TransactionParticipant::get(session).abortPreparedTransactionForRollback( - opCtx); + TransactionParticipant::get(session).abortTransaction(opCtx); + TransactionParticipant::get(session).invalidate(opCtx); }); } diff --git a/src/mongo/db/ops/write_ops_exec.cpp b/src/mongo/db/ops/write_ops_exec.cpp index d495bb89f35..c1e2c5722cf 100644 --- a/src/mongo/db/ops/write_ops_exec.cpp +++ b/src/mongo/db/ops/write_ops_exec.cpp @@ -252,7 +252,7 @@ bool handleError(OperationContext* opCtx, } // If we are in a transaction, we must fail the whole batch. out->results.emplace_back(ex.toStatus()); - txnParticipant.abortActiveTransaction(opCtx); + txnParticipant.abortTransaction(opCtx); return false; } diff --git a/src/mongo/db/repl/transaction_oplog_application.cpp b/src/mongo/db/repl/transaction_oplog_application.cpp index d06b41c2643..92cbee05379 100644 --- a/src/mongo/db/repl/transaction_oplog_application.cpp +++ b/src/mongo/db/repl/transaction_oplog_application.cpp @@ -219,7 +219,7 @@ Status applyAbortTransaction(OperationContext* opCtx, auto transaction = TransactionParticipant::get(opCtx); transaction.unstashTransactionResources(opCtx, "abortTransaction"); - transaction.abortActiveTransaction(opCtx); + transaction.abortTransaction(opCtx); return Status::OK(); } } diff --git a/src/mongo/db/s/txn_two_phase_commit_cmds.cpp b/src/mongo/db/s/txn_two_phase_commit_cmds.cpp index cbf6e0e0256..9bfebcef08b 100644 --- a/src/mongo/db/s/txn_two_phase_commit_cmds.cpp +++ b/src/mongo/db/s/txn_two_phase_commit_cmds.cpp @@ -280,16 +280,15 @@ public: { MongoDOperationContextSession sessionTxnState(opCtx); auto txnParticipant = TransactionParticipant::get(opCtx); - txnParticipant.beginOrContinue(opCtx, *opCtx->getTxnNumber(), false /* autocommit */, boost::none /* startTransaction */); - try { - txnParticipant.abortTransactionIfNotPrepared(opCtx); - } catch (const ExceptionFor<ErrorCodes::TransactionCommitted>&) { + if (txnParticipant.transactionIsCommitted()) return; + if (txnParticipant.transactionIsInProgress()) { + txnParticipant.abortTransaction(opCtx); } participantExitPrepareFuture = txnParticipant.onExitPrepare(); diff --git a/src/mongo/db/service_entry_point_common.cpp b/src/mongo/db/service_entry_point_common.cpp index a4117d0bd56..5b634561906 100644 --- a/src/mongo/db/service_entry_point_common.cpp +++ b/src/mongo/db/service_entry_point_common.cpp @@ -378,6 +378,25 @@ void appendClusterAndOperationTime(OperationContext* opCtx, operationTime.appendAsOperationTime(commandBodyFieldsBob); } +namespace { +void _abortUnpreparedOrStashPreparedTransaction( + OperationContext* opCtx, TransactionParticipant::Participant* txnParticipant) { + const bool isPrepared = txnParticipant->transactionIsPrepared(); + try { + if (isPrepared) + txnParticipant->stashTransactionResources(opCtx); + else if (txnParticipant->transactionIsOpen()) + txnParticipant->abortTransaction(opCtx); + } catch (...) { + // It is illegal for this to throw so we catch and log this here for diagnosability. + severe() << "Caught exception during transaction " << opCtx->getTxnNumber() + << (isPrepared ? " stash " : " abort ") << opCtx->getLogicalSessionId()->toBSON() + << ": " << exceptionToStatus(); + std::terminate(); + } +} +} // namespace + void invokeWithSessionCheckedOut(OperationContext* opCtx, CommandInvocation* invocation, const OperationSessionInfoFromClient& sessionOptions, @@ -411,8 +430,11 @@ void invokeWithSessionCheckedOut(OperationContext* opCtx, // transactions on failure to unstash the transaction resources to opCtx. We don't want to // have this error guard for beginOrContinue as it can abort the transaction for any // accidental invalid statements in the transaction. - auto abortOnError = makeGuard( - [&txnParticipant, opCtx] { txnParticipant.abortTransactionIfNotPrepared(opCtx); }); + auto abortOnError = makeGuard([&txnParticipant, opCtx] { + if (txnParticipant.transactionIsInProgress()) { + txnParticipant.abortTransaction(opCtx); + } + }); txnParticipant.unstashTransactionResources(opCtx, invocation->definition()->getName()); @@ -420,8 +442,8 @@ void invokeWithSessionCheckedOut(OperationContext* opCtx, abortOnError.dismiss(); } - auto guard = makeGuard([&txnParticipant, opCtx] { - txnParticipant.abortActiveUnpreparedOrStashPreparedTransaction(opCtx); + auto guard = makeGuard([opCtx, &txnParticipant] { + _abortUnpreparedOrStashPreparedTransaction(opCtx, &txnParticipant); }); try { diff --git a/src/mongo/db/session_catalog_mongod.cpp b/src/mongo/db/session_catalog_mongod.cpp index 24e6bf62bee..86aeb61fdeb 100644 --- a/src/mongo/db/session_catalog_mongod.cpp +++ b/src/mongo/db/session_catalog_mongod.cpp @@ -207,7 +207,7 @@ void abortInProgressTransactions(OperationContext* opCtx) { auto txnParticipant = TransactionParticipant::get(opCtx); LOG(3) << "Aborting transaction sessionId: " << txnRecord.getSessionId().toBSON() << " txnNumber " << txnRecord.getTxnNum(); - txnParticipant.abortTransactionForStepUp(opCtx); + txnParticipant.abortTransaction(opCtx); } } } // namespace diff --git a/src/mongo/db/transaction_metrics_observer.cpp b/src/mongo/db/transaction_metrics_observer.cpp index ad0ce535173..e1b36d971bd 100644 --- a/src/mongo/db/transaction_metrics_observer.cpp +++ b/src/mongo/db/transaction_metrics_observer.cpp @@ -138,18 +138,12 @@ void TransactionMetricsObserver::_onAbortActive( // Server wide transactions metrics. // serverTransactionsMetrics->decrementCurrentActive(); - - if (_singleTransactionStats.isPrepared()) { - serverTransactionsMetrics->incrementTotalPreparedThenAborted(); - serverTransactionsMetrics->decrementCurrentPrepared(); - } } void TransactionMetricsObserver::_onAbortInactive( ServerTransactionsMetrics* serverTransactionsMetrics, TickSource* tickSource, Top* top) { auto curTick = tickSource->getTicks(); invariant(!_singleTransactionStats.isActive()); - invariant(!_singleTransactionStats.isPrepared()); _onAbort(serverTransactionsMetrics, curTick, tickSource, top); // @@ -213,6 +207,11 @@ void TransactionMetricsObserver::_onAbort(ServerTransactionsMetrics* serverTrans serverTransactionsMetrics->incrementTotalAborted(); serverTransactionsMetrics->decrementCurrentOpen(); + if (_singleTransactionStats.isPrepared()) { + serverTransactionsMetrics->incrementTotalPreparedThenAborted(); + serverTransactionsMetrics->decrementCurrentPrepared(); + } + auto latency = durationCount<Microseconds>(_singleTransactionStats.getDuration(tickSource, curTick)); top->incrementGlobalTransactionLatencyStats(static_cast<uint64_t>(latency)); diff --git a/src/mongo/db/transaction_participant.cpp b/src/mongo/db/transaction_participant.cpp index 1e2327cdd3b..6fbfabbe359 100644 --- a/src/mongo/db/transaction_participant.cpp +++ b/src/mongo/db/transaction_participant.cpp @@ -554,6 +554,13 @@ void TransactionParticipant::Participant::beginOrContinueTransactionUnconditiona if (o().activeTxnNumber != txnNumber) { _beginMultiDocumentTransaction(opCtx, txnNumber); } + + // Assume we need to write an abort if we abort this transaction. This method is called only + // on secondaries (in which case we never write anything) and when a new primary knows about + // an in-progress transaction. If a new primary knows about an in-progress transaction, it + // needs an abort oplog entry to be written if aborted (because the new primary could not + // have found out if there wasn't an oplog entry for the new primary). + p().needToWriteAbortEntry = true; } SharedSemiFuture<void> TransactionParticipant::Participant::onExitPrepare() const { @@ -1040,11 +1047,11 @@ Timestamp TransactionParticipant::Participant::prepareTransaction( try { // This shouldn't cause deadlocks with other prepared txns, because the acquisition - // of RSTL lock inside abortActiveTransaction will be no-op since we already have it. + // of RSTL lock inside abortTransaction will be no-op since we already have it. // This abortGuard gets dismissed before we release the RSTL while transitioning to // prepared. UninterruptibleLockGuard noInterrupt(opCtx->lockState()); - abortActiveTransaction(opCtx); + abortTransaction(opCtx); } catch (...) { // It is illegal for aborting a prepared transaction to fail for any reason, so we crash // instead. @@ -1119,6 +1126,7 @@ Timestamp TransactionParticipant::Participant::prepareTransaction( } opCtx->recoveryUnit()->setPrepareTimestamp(prepareOplogSlot.getTimestamp()); opCtx->getWriteUnitOfWork()->prepare(); + p().needToWriteAbortEntry = true; opCtx->getServiceContext()->getOpObserver()->onTransactionPrepare( opCtx, reservedSlots, completedTransactionOperations); @@ -1434,26 +1442,22 @@ void TransactionParticipant::Participant::shutdown(OperationContext* opCtx) { o(lock).txnResourceStash = boost::none; } -void TransactionParticipant::Participant::abortTransactionIfNotPrepared(OperationContext* opCtx) { - if (!o().txnState.isInProgress()) { - // We do not want to abort transactions that are prepared unless we get an - // 'abortTransaction' command. - return; - } - - _abortTransactionOnSession(opCtx); -} - bool TransactionParticipant::Observer::expiredAsOf(Date_t when) const { return o().txnState.isInProgress() && o().transactionExpireDate && o().transactionExpireDate < when; } -void TransactionParticipant::Participant::abortActiveTransaction(OperationContext* opCtx) { - if (o().txnState.isPrepared()) { +void TransactionParticipant::Participant::abortTransaction(OperationContext* opCtx) { + // Normally, absence of a transaction resource stash indicates an inactive transaction. + // However, in the case of a failed "unstash", an active transaction may exist without a stash + // and be killed externally. In that case, the opCtx will not have a transaction number. + if (o().txnResourceStash || !opCtx->getTxnNumber()) { + // Aborting an inactive transaction. + _abortTransactionOnSession(opCtx); + } else if (o().txnState.isPrepared()) { _abortActivePreparedTransaction(opCtx); } else { - _abortActiveTransaction(opCtx, TransactionState::kInProgress, false); + _abortActiveTransaction(opCtx, TransactionState::kInProgress); } } @@ -1476,38 +1480,11 @@ void TransactionParticipant::Participant::_abortActivePreparedTransaction(Operat replCoord->canAcceptWritesForDatabase(opCtx, "admin")); } - _abortActiveTransaction(opCtx, TransactionState::kPrepared, true); -} - -void TransactionParticipant::Participant::abortActiveUnpreparedOrStashPreparedTransaction( - OperationContext* opCtx) try { - if (o().txnState.isInSet(TransactionState::kNone | TransactionState::kCommitted | - TransactionState::kExecutedRetryableWrite)) { - // If there is no active transaction, do nothing. - return; - } - - // Stash the transaction if it's in prepared state. - if (o().txnState.isInSet(TransactionState::kPrepared)) { - _stashActiveTransaction(opCtx); - return; - } - - _abortActiveTransaction(opCtx, TransactionState::kInProgress, false /* writeOplog */); -} catch (...) { - // It is illegal for this to throw so we catch and log this here for diagnosability. - severe() << "Caught exception during transaction " << opCtx->getTxnNumber() - << " abort or stash on " << _sessionId().toBSON() << " in state " << o().txnState - << ": " << exceptionToStatus(); - std::terminate(); -} - -void TransactionParticipant::Participant::abortTransactionForStepUp(OperationContext* opCtx) { - _abortActiveTransaction(opCtx, TransactionState::kInProgress, true); + _abortActiveTransaction(opCtx, TransactionState::kPrepared); } void TransactionParticipant::Participant::_abortActiveTransaction( - OperationContext* opCtx, TransactionState::StateSet expectedStates, bool writeOplog) { + OperationContext* opCtx, TransactionState::StateSet expectedStates) { invariant(!o().txnResourceStash); invariant(!o().txnState.isCommittingWithPrepare()); @@ -1522,7 +1499,7 @@ void TransactionParticipant::Participant::_abortActiveTransaction( // OpObserver. boost::optional<OplogSlotReserver> oplogSlotReserver; boost::optional<OplogSlot> abortOplogSlot; - if (opCtx->writesAreReplicated() && writeOplog) { + if (opCtx->writesAreReplicated() && p().needToWriteAbortEntry) { oplogSlotReserver.emplace(opCtx); abortOplogSlot = oplogSlotReserver->getLastSlot(); } @@ -1603,7 +1580,10 @@ void TransactionParticipant::Participant::_cleanUpTxnResourceOnOpCtx( // Reset the WUOW. We should be able to abort empty transactions that don't have WUOW. if (opCtx->getWriteUnitOfWork()) { - invariant(opCtx->lockState()->isRSTLLocked()); + // We could have failed trying to get the initial global lock; in that case we will have a + // WriteUnitOfWork but not have allocated the storage transaction. That is the only case + // where it is legal to abort a unit of work without the RSTL. + invariant(opCtx->lockState()->isRSTLLocked() || !opCtx->recoveryUnit()->inActiveTxn()); opCtx->setWriteUnitOfWork(nullptr); } @@ -2072,6 +2052,7 @@ void TransactionParticipant::Participant::_resetTransactionState( o(wl).prepareOpTime = repl::OpTime(); o(wl).recoveryPrepareOpTime = repl::OpTime(); p().autoCommit = boost::none; + p().needToWriteAbortEntry = false; // Release any locks held by this participant and abort the storage transaction. o(wl).txnResourceStash = boost::none; @@ -2092,23 +2073,6 @@ void TransactionParticipant::Participant::invalidate(OperationContext* opCtx) { _resetTransactionState(lg, TransactionState::kNone); } -void TransactionParticipant::Participant::abortPreparedTransactionForRollback( - OperationContext* opCtx) { - uassert(51030, - str::stream() << "Cannot call abortPreparedTransactionForRollback on unprepared " - << "transaction.", - o().txnState.isPrepared()); - - stdx::lock_guard<Client> lg(*opCtx->getClient()); - - // It should be safe to clear transactionOperationBytes and transactionOperations because - // we only modify these variables when adding an operation to a transaction. Since this - // transaction is already prepared, we cannot add more operations to it. We will have this - // in the prepare oplog entry. - _invalidate(lg); - _resetTransactionState(lg, TransactionState::kNone); -} - boost::optional<repl::OplogEntry> TransactionParticipant::Participant::checkStatementExecuted( OperationContext* opCtx, StmtId stmtId) const { const auto stmtTimestamp = _checkStatementExecuted(stmtId); diff --git a/src/mongo/db/transaction_participant.h b/src/mongo/db/transaction_participant.h index 897637b9f32..93a509a90c1 100644 --- a/src/mongo/db/transaction_participant.h +++ b/src/mongo/db/transaction_participant.h @@ -495,34 +495,10 @@ public: Timestamp commitTimestamp, boost::optional<repl::OpTime> commitOplogEntryOpTime); - /** - * Aborts the transaction, if it is not in the "prepared" state. - */ - void abortTransactionIfNotPrepared(OperationContext* opCtx); - /* * Aborts the transaction, releasing transaction resources. */ - void abortActiveTransaction(OperationContext* opCtx); - - /* - * If the transaction is prepared, stash its resources. If not, it's the same as - * abortActiveTransaction. - */ - void abortActiveUnpreparedOrStashPreparedTransaction(OperationContext* opCtx); - - /** - * Abort the transaction and write an abort oplog entry unconditionally. - */ - void abortTransactionForStepUp(OperationContext* opCtx); - - /** - * Aborts the storage transaction of the prepared transaction on this participant by - * releasing its resources. Also invalidates the session and the current transaction state. - * Avoids writing any oplog entries or making any changes to the transaction table since the - * state for prepared transactions will be re-constituted during replication recovery. - */ - void abortPreparedTransactionForRollback(OperationContext* opCtx); + void abortTransaction(OperationContext* opCtx); /** * Adds a stored operation to the list of stored operations for the current multi-document @@ -701,11 +677,10 @@ public: void _stashActiveTransaction(OperationContext* opCtx); // Abort the transaction if it's in one of the expected states and clean up the transaction - // states associated with the opCtx. - // If 'writeOplog' is true, logs an 'abortTransaction' oplog entry if writes are replicated. + // states associated with the opCtx. Write an abort oplog entry if specified by the + // needToWriteAbortEntry state bool. void _abortActiveTransaction(OperationContext* opCtx, - TransactionState::StateSet expectedStates, - bool writeOplog); + TransactionState::StateSet expectedStates); // Aborts a prepared transaction. void _abortActivePreparedTransaction(OperationContext* opCtx); @@ -954,6 +929,12 @@ private: // opTime. Used for fast retryability check and retrieving the previous write's data without // having to scan through the oplog. CommittedStatementTimestampMap activeTxnCommittedStatements; + + // Set to true if we need to write an "abort" oplog entry in the case of an abort. This + // is the case when we have (or may have) written or replicated an oplog entry for the + // transaction. + bool needToWriteAbortEntry{false}; + } _p; }; diff --git a/src/mongo/db/transaction_participant_test.cpp b/src/mongo/db/transaction_participant_test.cpp index 0947c8580ae..497ef46b756 100644 --- a/src/mongo/db/transaction_participant_test.cpp +++ b/src/mongo/db/transaction_participant_test.cpp @@ -495,7 +495,7 @@ TEST_F(TxnParticipantTest, AbortClearsStoredStatements) { // The transaction machinery cannot store an empty locker. { Lock::GlobalLock lk(opCtx(), MODE_IX, Date_t::now(), Lock::InterruptBehavior::kThrow); } txnParticipant.stashTransactionResources(opCtx()); - txnParticipant.abortTransactionIfNotPrepared(opCtx()); + txnParticipant.abortTransaction(opCtx()); ASSERT_TRUE(txnParticipant.getTransactionOperationsForTest().empty()); ASSERT_TRUE(txnParticipant.transactionIsAborted()); } @@ -709,7 +709,7 @@ TEST_F(TxnParticipantTest, EmptyTransactionAbort) { // The transaction machinery cannot store an empty locker. { Lock::GlobalLock lk(opCtx(), MODE_IX, Date_t::now(), Lock::InterruptBehavior::kThrow); } txnParticipant.stashTransactionResources(opCtx()); - txnParticipant.abortTransactionIfNotPrepared(opCtx()); + txnParticipant.abortTransaction(opCtx()); ASSERT_TRUE(txnParticipant.transactionIsAborted()); } @@ -723,37 +723,10 @@ TEST_F(TxnParticipantTest, EmptyPreparedTransactionAbort) { // The transaction machinery cannot store an empty locker. { Lock::GlobalLock lk(opCtx(), MODE_IX, Date_t::now(), Lock::InterruptBehavior::kThrow); } txnParticipant.prepareTransaction(opCtx(), {}); - txnParticipant.abortActiveTransaction(opCtx()); + txnParticipant.abortTransaction(opCtx()); ASSERT_TRUE(txnParticipant.transactionIsAborted()); } -TEST_F(TxnParticipantTest, KillSessionsDuringPrepareDoesNotAbortTransaction) { - auto sessionCheckout = checkOutSession(); - auto txnParticipant = TransactionParticipant::get(opCtx()); - - txnParticipant.unstashTransactionResources(opCtx(), "prepareTransaction"); - - auto ruPrepareTimestamp = Timestamp(); - auto originalFn = _opObserver->onTransactionPrepareFn; - _opObserver->onTransactionPrepareFn = [&]() { - originalFn(); - - ruPrepareTimestamp = opCtx()->recoveryUnit()->getPrepareTimestamp(); - ASSERT_FALSE(ruPrepareTimestamp.isNull()); - - // The transaction may be aborted without checking out the txnParticipant. - txnParticipant.abortTransactionIfNotPrepared(opCtx()); - ASSERT_FALSE(txnParticipant.transactionIsAborted()); - }; - - // Check that prepareTimestamp gets set. - auto prepareTimestamp = txnParticipant.prepareTransaction(opCtx(), {}); - ASSERT_EQ(ruPrepareTimestamp, prepareTimestamp); - - ASSERT(_opObserver->transactionPrepared); - ASSERT_FALSE(txnParticipant.transactionIsAborted()); -} - TEST_F(TxnParticipantTest, ThrowDuringOnTransactionPrepareAbortsTransaction) { auto sessionCheckout = checkOutSession(); auto txnParticipant = TransactionParticipant::get(opCtx()); @@ -829,7 +802,7 @@ TEST_F(TxnParticipantTest, StepDownAfterPrepareDoesNotBlock) { }; runFunctionFromDifferentOpCtx(func); - txnParticipant.abortActiveTransaction(opCtx()); + txnParticipant.abortTransaction(opCtx()); ASSERT(_opObserver->transactionAborted); ASSERT(txnParticipant.transactionIsAborted()); } @@ -861,7 +834,7 @@ TEST_F(TxnParticipantTest, StepDownDuringAbortSucceeds) { ASSERT_OK(repl::ReplicationCoordinator::get(opCtx())->setFollowerMode( repl::MemberState::RS_SECONDARY)); - txnParticipant.abortActiveTransaction(opCtx()); + txnParticipant.abortTransaction(opCtx()); ASSERT(_opObserver->transactionAborted); ASSERT(txnParticipant.transactionIsAborted()); } @@ -876,7 +849,7 @@ TEST_F(TxnParticipantTest, StepDownDuringPreparedAbortFails) { ASSERT_OK(repl::ReplicationCoordinator::get(opCtx())->setFollowerMode( repl::MemberState::RS_SECONDARY)); ASSERT_THROWS_CODE( - txnParticipant.abortActiveTransaction(opCtx()), AssertionException, ErrorCodes::NotMaster); + txnParticipant.abortTransaction(opCtx()), AssertionException, ErrorCodes::NotMaster); } TEST_F(TxnParticipantTest, StepDownDuringPreparedCommitFails) { @@ -932,7 +905,7 @@ TEST_F(TxnParticipantTest, StepDownDuringPreparedAbortReleasesRSTL) { ASSERT_OK(repl::ReplicationCoordinator::get(opCtx())->setFollowerMode( repl::MemberState::RS_SECONDARY)); ASSERT_THROWS_CODE( - txnParticipant.abortActiveTransaction(opCtx()), AssertionException, ErrorCodes::NotMaster); + txnParticipant.abortTransaction(opCtx()), AssertionException, ErrorCodes::NotMaster); ASSERT_EQ(opCtx()->lockState()->getLockMode(resourceIdReplicationStateTransitionLock), MODE_NONE); @@ -1015,7 +988,7 @@ TEST_F(TxnParticipantTest, ThrowDuringUnpreparedCommitLetsTheAbortAtEntryPointTo ASSERT_FALSE(txnParticipant.transactionIsCommitted()); // Simulate the abort at entry point. - txnParticipant.abortActiveUnpreparedOrStashPreparedTransaction(opCtx()); + txnParticipant.abortTransaction(opCtx()); ASSERT_TRUE(txnParticipant.transactionIsAborted()); } @@ -1033,56 +1006,6 @@ TEST_F(TxnParticipantTest, ContinuingATransactionWithNoResourcesAborts) { ErrorCodes::NoSuchTransaction); } -TEST_F(TxnParticipantTest, KillSessionsDoesNotAbortPreparedTransactions) { - auto sessionCheckout = checkOutSession(); - auto txnParticipant = TransactionParticipant::get(opCtx()); - - txnParticipant.unstashTransactionResources(opCtx(), "insert"); - - auto ruPrepareTimestamp = Timestamp(); - auto originalFn = _opObserver->onTransactionPrepareFn; - _opObserver->onTransactionPrepareFn = [&]() { - originalFn(); - ruPrepareTimestamp = opCtx()->recoveryUnit()->getPrepareTimestamp(); - ASSERT_FALSE(ruPrepareTimestamp.isNull()); - }; - - // Check that prepareTimestamp gets set. - auto prepareTimestamp = txnParticipant.prepareTransaction(opCtx(), {}); - ASSERT_EQ(ruPrepareTimestamp, prepareTimestamp); - - txnParticipant.stashTransactionResources(opCtx()); - - txnParticipant.abortTransactionIfNotPrepared(opCtx()); - ASSERT_FALSE(txnParticipant.transactionIsAborted()); - ASSERT(_opObserver->transactionPrepared); -} - -TEST_F(TxnParticipantTest, CannotAbortArbitraryPreparedTransactions) { - auto sessionCheckout = checkOutSession(); - auto txnParticipant = TransactionParticipant::get(opCtx()); - - txnParticipant.unstashTransactionResources(opCtx(), "insert"); - - auto ruPrepareTimestamp = Timestamp(); - auto originalFn = _opObserver->onTransactionPrepareFn; - _opObserver->onTransactionPrepareFn = [&]() { - originalFn(); - ruPrepareTimestamp = opCtx()->recoveryUnit()->getPrepareTimestamp(); - ASSERT_FALSE(ruPrepareTimestamp.isNull()); - }; - - // Check that prepareTimestamp gets set. - auto prepareTimestamp = txnParticipant.prepareTransaction(opCtx(), {}); - ASSERT_EQ(ruPrepareTimestamp, prepareTimestamp); - - txnParticipant.stashTransactionResources(opCtx()); - - txnParticipant.abortTransactionIfNotPrepared(opCtx()); - ASSERT(!txnParticipant.transactionIsAborted()); - ASSERT(_opObserver->transactionPrepared); -} - TEST_F(TxnParticipantTest, CannotStartNewTransactionIfNotPrimary) { ASSERT_OK(repl::ReplicationCoordinator::get(opCtx())->setFollowerMode( repl::MemberState::RS_SECONDARY)); @@ -1190,23 +1113,6 @@ TEST_F(TxnParticipantTest, CannotInsertInPreparedTransaction) { ASSERT(_opObserver->transactionPrepared); } -TEST_F(TxnParticipantTest, ImplicitAbortDoesNotAbortPreparedTransaction) { - auto outerScopedSession = checkOutSession(); - auto txnParticipant = TransactionParticipant::get(opCtx()); - - txnParticipant.unstashTransactionResources(opCtx(), "insert"); - auto operation = repl::OplogEntry::makeInsertOperation(kNss, _uuid, BSON("TestValue" << 0)); - txnParticipant.addTransactionOperation(opCtx(), operation); - - txnParticipant.prepareTransaction(opCtx(), {}); - - // The next command throws an exception and wants to abort the transaction. - // This is a no-op. - txnParticipant.abortActiveUnpreparedOrStashPreparedTransaction(opCtx()); - ASSERT_FALSE(txnParticipant.transactionIsAborted()); - ASSERT_TRUE(_opObserver->transactionPrepared); -} - DEATH_TEST_F(TxnParticipantTest, AbortIsIllegalDuringCommittingPreparedTransaction, "isCommittingWithPrepare") { @@ -1224,7 +1130,7 @@ DEATH_TEST_F(TxnParticipantTest, Timestamp commitTimestamp, const std::vector<repl::ReplOperation>& statements) { // Hit an invariant. This should never happen. - txnParticipant.abortActiveTransaction(opCtx()); + txnParticipant.abortTransaction(opCtx()); ASSERT_FALSE(txnParticipant.transactionIsAborted()); }; @@ -1334,7 +1240,7 @@ protected: auto txnParticipant = TransactionParticipant::get(opCtx()); ASSERT(txnParticipant.transactionIsOpen()); - txnParticipant.abortActiveTransaction(opCtx()); + txnParticipant.abortTransaction(opCtx()); ASSERT(txnParticipant.transactionIsAborted()); txnParticipant.beginOrContinue( @@ -1390,7 +1296,7 @@ protected: txnParticipant.prepareTransaction(opCtx(), {}); ASSERT(txnParticipant.transactionIsPrepared()); - txnParticipant.abortActiveTransaction(opCtx()); + txnParticipant.abortTransaction(opCtx()); ASSERT(txnParticipant.transactionIsAborted()); startTransaction = true; @@ -1504,9 +1410,8 @@ TEST_F(TxnParticipantTest, ThrowDuringUnpreparedOnTransactionAbort) { _opObserver->onTransactionAbortThrowsException = true; - ASSERT_THROWS_CODE(txnParticipant.abortActiveTransaction(opCtx()), - AssertionException, - ErrorCodes::OperationFailed); + ASSERT_THROWS_CODE( + txnParticipant.abortTransaction(opCtx()), AssertionException, ErrorCodes::OperationFailed); } TEST_F(TxnParticipantTest, ThrowDuringPreparedOnTransactionAbortIsFatal) { @@ -1517,9 +1422,8 @@ TEST_F(TxnParticipantTest, ThrowDuringPreparedOnTransactionAbortIsFatal) { _opObserver->onTransactionAbortThrowsException = true; - ASSERT_THROWS_CODE(txnParticipant.abortActiveTransaction(opCtx()), - AssertionException, - ErrorCodes::OperationFailed); + ASSERT_THROWS_CODE( + txnParticipant.abortTransaction(opCtx()), AssertionException, ErrorCodes::OperationFailed); } TEST_F(TxnParticipantTest, InterruptedSessionsCannotBePrepared) { @@ -1584,7 +1488,7 @@ TEST_F(TxnParticipantTest, ReacquireLocksForPreparedTransactionsOnStepUp) { auto txnParticipant = TransactionParticipant::get(opCtx()); ASSERT(txnParticipant.getTxnResourceStashLockerForTest()->isLocked()); txnParticipant.unstashTransactionResources(opCtx(), "abortTransaction"); - txnParticipant.abortActiveTransaction(opCtx()); + txnParticipant.abortTransaction(opCtx()); } } @@ -1679,7 +1583,7 @@ TEST_F(TransactionsMetricsTest, IncrementTotalAbortedUponAbort) { unsigned long long beforeAbortCount = ServerTransactionsMetrics::get(opCtx())->getTotalAborted(); - txnParticipant.abortTransactionIfNotPrepared(opCtx()); + txnParticipant.abortTransaction(opCtx()); // Assert that the aborted counter is incremented by 1. ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getTotalAborted(), beforeAbortCount + 1U); @@ -1694,7 +1598,7 @@ TEST_F(TransactionsMetricsTest, IncrementTotalPreparedThenAborted) { txnParticipant.unstashTransactionResources(opCtx(), "prepareTransaction"); txnParticipant.prepareTransaction(opCtx(), {}); - txnParticipant.abortActiveTransaction(opCtx()); + txnParticipant.abortTransaction(opCtx()); ASSERT(txnParticipant.transactionIsAborted()); ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getTotalPreparedThenAborted(), beforePreparedThenAbortedCount + 1U); @@ -1728,7 +1632,7 @@ TEST_F(TransactionsMetricsTest, IncrementCurrentPreparedWithAbort) { ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getCurrentPrepared(), beforeCurrentPrepared + 1U); - txnParticipant.abortActiveTransaction(opCtx()); + txnParticipant.abortTransaction(opCtx()); ASSERT(txnParticipant.transactionIsAborted()); ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getCurrentPrepared(), beforeCurrentPrepared); } @@ -1761,7 +1665,8 @@ TEST_F(TransactionsMetricsTest, NoPreparedMetricsChangesAfterExceptionInPrepare) ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getTotalPreparedThenAborted(), beforeTotalPreparedThenAborted); - txnParticipant.abortActiveTransaction(opCtx()); + if (txnParticipant.transactionIsOpen()) + txnParticipant.abortTransaction(opCtx()); ASSERT(txnParticipant.transactionIsAborted()); ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getCurrentPrepared(), beforeCurrentPrepared); @@ -1790,7 +1695,7 @@ TEST_F(TransactionsMetricsTest, TrackTotalOpenTransactionsWithAbort) { beforeTransactionStart + 1U); // Tests that aborting a transaction decrements the open transactions counter by 1. - txnParticipant.abortTransactionIfNotPrepared(opCtx()); + txnParticipant.abortTransaction(opCtx()); ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getCurrentOpen(), beforeTransactionStart); } @@ -1886,7 +1791,7 @@ TEST_F(TransactionsMetricsTest, TrackTotalActiveAndInactiveTransactionsWithStash beforeInactiveCounter + 1U); // Tests that aborting a stashed transaction decrements the inactive counter only. - txnParticipant.abortTransactionIfNotPrepared(opCtx()); + txnParticipant.abortTransaction(opCtx()); ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getCurrentActive(), beforeActiveCounter); ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getCurrentInactive(), beforeInactiveCounter); } @@ -1911,7 +1816,7 @@ TEST_F(TransactionsMetricsTest, TrackTotalActiveAndInactiveTransactionsWithUnsta ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getCurrentInactive(), beforeInactiveCounter); // Tests that aborting a stashed transaction decrements the active counter only. - txnParticipant.abortTransactionIfNotPrepared(opCtx()); + txnParticipant.abortTransaction(opCtx()); ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getCurrentActive(), beforeActiveCounter); ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getCurrentInactive(), beforeInactiveCounter); } @@ -1996,7 +1901,7 @@ TEST_F(TransactionsMetricsTest, beforeActivePreparedCounter + 1U); ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getCurrentInactive(), beforeInactivePreparedCounter); - txnParticipant.abortActiveTransaction(opCtx()); + txnParticipant.abortTransaction(opCtx()); ASSERT(txnParticipant.transactionIsAborted()); ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getCurrentActive(), beforeActivePreparedCounter); @@ -2091,7 +1996,7 @@ TEST_F(TransactionsMetricsTest, SingleTransactionStatsDurationShouldBeSetUponAbo // Advance the clock. tickSource->advance(Microseconds(100)); - txnParticipant.abortTransactionIfNotPrepared(opCtx()); + txnParticipant.abortTransaction(opCtx()); ASSERT_EQ(txnParticipant.getSingleTransactionStatsForTest().getDuration(tickSource, tickSource->getTicks()), Microseconds(100)); @@ -2111,7 +2016,7 @@ TEST_F(TransactionsMetricsTest, SingleTransactionStatsPreparedDurationShouldBeSe txnParticipant.prepareTransaction(opCtx(), {}); tickSource->advance(Microseconds(100)); - txnParticipant.abortActiveTransaction(opCtx()); + txnParticipant.abortTransaction(opCtx()); ASSERT_EQ(txnParticipant.getSingleTransactionStatsForTest().getPreparedDuration( tickSource, tickSource->getTicks()), Microseconds(100)); @@ -2202,7 +2107,7 @@ TEST_F(TransactionsMetricsTest, SingleTransactionStatsDurationShouldKeepIncreasi tickSource->advance(Microseconds(100)); // Abort the transaction and check duration. - txnParticipant.abortTransactionIfNotPrepared(opCtx()); + txnParticipant.abortTransaction(opCtx()); ASSERT_EQ(txnParticipant.getSingleTransactionStatsForTest().getDuration(tickSource, tickSource->getTicks()), Microseconds(200)); @@ -2236,7 +2141,7 @@ TEST_F(TransactionsMetricsTest, tickSource->advance(Microseconds(100)); // Abort the prepared transaction and check the prepared duration. - txnParticipant.abortActiveTransaction(opCtx()); + txnParticipant.abortTransaction(opCtx()); ASSERT_EQ(txnParticipant.getSingleTransactionStatsForTest().getPreparedDuration( tickSource, tickSource->getTicks()), Microseconds(200)); @@ -2309,7 +2214,7 @@ TEST_F(TransactionsMetricsTest, TimeActiveMicrosShouldBeSetUponUnstashAndAbort) txnParticipant.unstashTransactionResources(opCtx(), "insert"); tickSource->advance(Microseconds(100)); - txnParticipant.abortTransactionIfNotPrepared(opCtx()); + txnParticipant.abortTransaction(opCtx()); // Time active should have increased. ASSERT_EQ(txnParticipant.getSingleTransactionStatsForTest().getTimeActiveMicros( @@ -2338,7 +2243,7 @@ TEST_F(TransactionsMetricsTest, TimeActiveMicrosShouldNotBeSetUponAbortOnly) { // Advance clock during inactive period. tickSource->advance(Microseconds(100)); - txnParticipant.abortTransactionIfNotPrepared(opCtx()); + txnParticipant.abortTransaction(opCtx()); // Time active should still be zero. ASSERT_EQ(txnParticipant.getSingleTransactionStatsForTest().getTimeActiveMicros( @@ -2531,7 +2436,7 @@ TEST_F(TransactionsMetricsTest, AdditiveMetricsObjectsShouldBeAddedTogetherUponA txnParticipant.unstashTransactionResources(opCtx(), "insert"); // The transaction machinery cannot store an empty locker. { Lock::GlobalLock lk(opCtx(), MODE_IX, Date_t::now(), Lock::InterruptBehavior::kThrow); } - txnParticipant.abortActiveTransaction(opCtx()); + txnParticipant.abortTransaction(opCtx()); ASSERT(txnParticipant.getSingleTransactionStatsForTest().getOpDebug()->additiveMetrics.equals( additiveMetricsToCompare)); @@ -2595,7 +2500,7 @@ TEST_F(TransactionsMetricsTest, TimeInactiveMicrosShouldBeSetUponUnstashAndAbort Microseconds{100}); txnParticipant.unstashTransactionResources(opCtx(), "insert"); - txnParticipant.abortTransactionIfNotPrepared(opCtx()); + txnParticipant.abortTransaction(opCtx()); ASSERT_EQ(txnParticipant.getSingleTransactionStatsForTest().getTimeInactiveMicros( tickSource, tickSource->getTicks()), @@ -2928,7 +2833,7 @@ TEST_F(TransactionsMetricsTest, LastClientInfoShouldUpdateUponAbort) { auto sessionCheckout = checkOutSession(); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant.unstashTransactionResources(opCtx(), "insert"); - txnParticipant.abortActiveTransaction(opCtx()); + txnParticipant.abortTransaction(opCtx()); // LastClientInfo should have been set. auto lastClientInfo = txnParticipant.getSingleTransactionStatsForTest().getLastClientInfo(); @@ -3198,7 +3103,7 @@ TEST_F(TransactionsMetricsTest, TestTransactionInfoForLogAfterAbort) { auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant.unstashTransactionResources(opCtx(), "abortTransaction"); - txnParticipant.abortActiveTransaction(opCtx()); + txnParticipant.abortTransaction(opCtx()); const auto lockerInfo = opCtx()->lockState()->getLockerInfo(boost::none); ASSERT(lockerInfo); @@ -3242,7 +3147,7 @@ TEST_F(TransactionsMetricsTest, TestPreparedTransactionInfoForLogAfterAbort) { txnParticipant.prepareTransaction(opCtx(), {}); tickSource->advance(Microseconds(10)); - txnParticipant.abortActiveTransaction(opCtx()); + txnParticipant.abortTransaction(opCtx()); const auto lockerInfo = opCtx()->lockState()->getLockerInfo(boost::none); ASSERT(lockerInfo); @@ -3385,7 +3290,7 @@ TEST_F(TransactionsMetricsTest, LogTransactionInfoAfterSlowAbort) { tickSource->advance(Microseconds(11 * 1000)); startCapturingLogMessages(); - txnParticipant.abortActiveTransaction(opCtx()); + txnParticipant.abortTransaction(opCtx()); stopCapturingLogMessages(); const auto lockerInfo = opCtx()->lockState()->getLockerInfo(boost::none); @@ -3430,7 +3335,7 @@ TEST_F(TransactionsMetricsTest, LogPreparedTransactionInfoAfterSlowAbort) { auto prepareOpTime = txnParticipant.getPrepareOpTime(); startCapturingLogMessages(); - txnParticipant.abortActiveTransaction(opCtx()); + txnParticipant.abortTransaction(opCtx()); stopCapturingLogMessages(); const auto lockerInfo = opCtx()->lockState()->getLockerInfo(boost::none); @@ -3528,7 +3433,7 @@ TEST_F(TransactionsMetricsTest, LogTransactionInfoAfterSlowStashedAbort) { tickSource->advance(Microseconds(11 * 1000)); startCapturingLogMessages(); - txnParticipant.abortTransactionIfNotPrepared(opCtx()); + txnParticipant.abortTransaction(opCtx()); stopCapturingLogMessages(); std::string expectedTransactionInfo = "transaction parameters"; @@ -3613,9 +3518,10 @@ TEST_F(TxnParticipantTest, RollbackResetsInMemoryStateOfPreparedTransaction) { ASSERT_EQ(txnParticipant.getPrepareOpTime().getTimestamp(), prepareTimestamp); ASSERT_NE(txnParticipant.getActiveTxnNumber(), kUninitializedTxnNumber); - txnParticipant.abortPreparedTransactionForRollback(opCtx()); + txnParticipant.abortTransaction(opCtx()); + txnParticipant.invalidate(opCtx()); - // After calling abortPreparedTransactionForRollback, the state of txnParticipant should be + // After calling abortTransaction and invalidate, the state of txnParticipant should be // invalidated. ASSERT_FALSE(txnParticipant.transactionIsPrepared()); ASSERT_EQ(txnParticipant.getTransactionOperationsForTest().size(), 0U); @@ -3728,7 +3634,7 @@ TEST_F(TxnParticipantTest, AbortTransactionOnSessionCheckoutWithoutRefresh) { ASSERT_EQ(txnParticipant.getActiveTxnNumber(), txnNumber); txnParticipant.unstashTransactionResources(opCtx(), "abortTransaction"); - txnParticipant.abortActiveTransaction(opCtx()); + txnParticipant.abortTransaction(opCtx()); ASSERT_TRUE(txnParticipant.transactionIsAborted()); } @@ -3798,7 +3704,7 @@ TEST_F(TxnParticipantTest, ResponseMetadataHasReadOnlyFalseIfAborted) { txnParticipant.unstashTransactionResources(opCtx(), "find"); ASSERT_TRUE(txnParticipant.getResponseMetadata().getReadOnly()); - txnParticipant.abortActiveTransaction(opCtx()); + txnParticipant.abortTransaction(opCtx()); ASSERT_FALSE(txnParticipant.getResponseMetadata().getReadOnly()); } @@ -3904,7 +3810,7 @@ TEST_F(TxnParticipantTest, ExitPreparePromiseIsFulfilledOnAbortAfterPrepare) { const auto exitPrepareFuture = txnParticipant.onExitPrepare(); ASSERT_FALSE(exitPrepareFuture.isReady()); - txnParticipant.abortActiveTransaction(opCtx()); + txnParticipant.abortTransaction(opCtx()); ASSERT_TRUE(exitPrepareFuture.isReady()); // Once the promise has been fulfilled, new callers of onExitPrepare should immediately be @@ -3912,7 +3818,7 @@ TEST_F(TxnParticipantTest, ExitPreparePromiseIsFulfilledOnAbortAfterPrepare) { ASSERT_TRUE(txnParticipant.onExitPrepare().isReady()); // abortTransaction is retryable, but does not cause the completion promise to be set again. - txnParticipant.abortActiveTransaction(opCtx()); + txnParticipant.abortTransaction(opCtx()); } TEST_F(TxnParticipantTest, ExitPreparePromiseIsFulfilledOnCommitAfterPrepare) { @@ -3941,28 +3847,5 @@ TEST_F(TxnParticipantTest, ExitPreparePromiseIsFulfilledOnCommitAfterPrepare) { ASSERT_TRUE(txnParticipant.onExitPrepare().isReady()); } -TEST_F(TxnParticipantTest, ExitPreparePromiseIsFulfilledOnAbortPreparedTransactionForRollback) { - MongoDOperationContextSession opCtxSession(opCtx()); - auto txnParticipant = TransactionParticipant::get(opCtx()); - - txnParticipant.beginOrContinue( - opCtx(), *opCtx()->getTxnNumber(), false /* autocommit */, true /* startTransaction */); - ASSERT_TRUE(txnParticipant.onExitPrepare().isReady()); - - txnParticipant.unstashTransactionResources(opCtx(), "find"); - ASSERT_TRUE(txnParticipant.onExitPrepare().isReady()); - - const auto prepareOpTime = repl::OpTime({3, 2}, 0); - txnParticipant.prepareTransaction(opCtx(), prepareOpTime); - const auto exitPrepareFuture = txnParticipant.onExitPrepare(); - ASSERT_FALSE(exitPrepareFuture.isReady()); - - txnParticipant.abortPreparedTransactionForRollback(opCtx()); - ASSERT_TRUE(exitPrepareFuture.isReady()); - - // Once the promise has been fulfilled, new callers of onExitPrepare should immediately be - // ready. - ASSERT_TRUE(txnParticipant.onExitPrepare().isReady()); -} } // namespace } // namespace mongo diff --git a/src/mongo/dbtests/storage_timestamp_tests.cpp b/src/mongo/dbtests/storage_timestamp_tests.cpp index bf5deafc338..ea4dc1e148b 100644 --- a/src/mongo/dbtests/storage_timestamp_tests.cpp +++ b/src/mongo/dbtests/storage_timestamp_tests.cpp @@ -3139,7 +3139,7 @@ public: txnParticipant.unstashTransactionResources(_opCtx, "abortTransaction"); - txnParticipant.abortActiveTransaction(_opCtx); + txnParticipant.abortTransaction(_opCtx); txnParticipant.stashTransactionResources(_opCtx); { @@ -3361,7 +3361,7 @@ public: } txnParticipant.unstashTransactionResources(_opCtx, "abortTransaction"); - txnParticipant.abortActiveTransaction(_opCtx); + txnParticipant.abortTransaction(_opCtx); assertNoStartOpTime(); txnParticipant.stashTransactionResources(_opCtx); |