diff options
| -rw-r--r-- | jstests/concurrency/fsm_workload_helpers/cleanup_txns.js | 4 | ||||
| -rw-r--r-- | src/mongo/s/transaction_router.cpp | 8 | ||||
| -rw-r--r-- | src/mongo/s/transaction_router_test.cpp | 31 |
3 files changed, 31 insertions, 12 deletions
diff --git a/jstests/concurrency/fsm_workload_helpers/cleanup_txns.js b/jstests/concurrency/fsm_workload_helpers/cleanup_txns.js index 9fb5a3f9a8d..92a7552c37e 100644 --- a/jstests/concurrency/fsm_workload_helpers/cleanup_txns.js +++ b/jstests/concurrency/fsm_workload_helpers/cleanup_txns.js @@ -17,7 +17,9 @@ function abortTransaction(sessionAwareDB, txnNumber) { ErrorCodes.TransactionCommitted, ErrorCodes.TransactionTooOld, ErrorCodes.Interrupted, - ErrorCodes.LockTimeout + ErrorCodes.LockTimeout, + // TransactionRouter will error when trying to abort txns that have not been started + 8027900 ]; const abortCmd = { abortTransaction: 1, diff --git a/src/mongo/s/transaction_router.cpp b/src/mongo/s/transaction_router.cpp index e7ce7314fb0..66465221f8b 100644 --- a/src/mongo/s/transaction_router.cpp +++ b/src/mongo/s/transaction_router.cpp @@ -1023,6 +1023,14 @@ void TransactionRouter::Router::beginOrContinueTxn(OperationContext* opCtx, repl::ReadConcernArgs::get(opCtx) = o().readConcernArgs; ++p().latestStmtId; + + uassert(8027900, + str::stream() + << "attempting to continue transaction that was not started lsid: " + << _sessionId() << " txnNumber: " << o().txnNumber, + o().atClusterTimeForSnapshotReadConcern || + o().placementConflictTimeForNonSnapshotReadConcern); + _onContinue(opCtx); break; } diff --git a/src/mongo/s/transaction_router_test.cpp b/src/mongo/s/transaction_router_test.cpp index 7153a7d0b55..67eef528ec7 100644 --- a/src/mongo/s/transaction_router_test.cpp +++ b/src/mongo/s/transaction_router_test.cpp @@ -2221,6 +2221,26 @@ TEST_F(TransactionRouterTest, ImplicitAbortIgnoresErrors) { future.default_timed_get(); } +TEST_F(TransactionRouterTest, CannotContinueAfterCommit) { + LogicalSessionId lsid(makeLogicalSessionIdForTest()); + TxnNumber txnNum{3}; + + auto opCtx = operationContext(); + opCtx->setLogicalSessionId(lsid); + opCtx->setTxnNumber(txnNum); + + RouterOperationContextSession scopedSession(opCtx); + auto txnRouter = TransactionRouter::get(opCtx); + + txnRouter.beginOrContinueTxn( + operationContext(), txnNum, TransactionRouter::TransactionActions::kCommit); + txnRouter.setDefaultAtClusterTime(operationContext()); + + ASSERT_THROWS(txnRouter.beginOrContinueTxn( + opCtx, txnNum, TransactionRouter::TransactionActions::kContinue), + AssertionException); +} + TEST_F(TransactionRouterTestWithDefaultSession, AbortPropagatesWriteConcern) { TxnNumber txnNum{3}; auto opCtx = operationContext(); @@ -4287,17 +4307,6 @@ TEST_F(TransactionRouterMetricsTest, RouterMetricsCurrent_Stash) { ASSERT_EQUALS(1L, routerTxnMetrics()->getCurrentInactive()); } -TEST_F(TransactionRouterMetricsTest, RouterMetricsCurrent_BeginAfterStash) { - beginRecoverCommitWithDefaultTxnNumber(); - txnRouter().stash(operationContext()); - txnRouter().beginOrContinueTxn( - operationContext(), kTxnNumber, TransactionRouter::TransactionActions::kContinue); - - ASSERT_EQUALS(1L, routerTxnMetrics()->getCurrentOpen()); - ASSERT_EQUALS(1L, routerTxnMetrics()->getCurrentActive()); - ASSERT_EQUALS(0L, routerTxnMetrics()->getCurrentInactive()); -} - TEST_F(TransactionRouterMetricsTest, RouterMetricsCurrent_AreNotCumulative) { // Test active. beginTxnWithDefaultTxnNumber(); |
