diff options
| author | Randolph Tan <randolph@10gen.com> | 2023-08-24 18:22:17 +0000 |
|---|---|---|
| committer | MongoDB Bot <mongo-bot@mongodb.com> | 2024-02-13 08:46:45 +0000 |
| commit | 89d6ffe6fc67b36fd47aff6425087003966588e3 (patch) | |
| tree | bbcd4ee88b2f73c382d20d163d58daf94c46780d | |
| parent | d5e6165f37d313bbd20dd22f379f64a384bf93b8 (diff) | |
SERVER-80279 Disallow continuing a transaction router that was not startedr4.4.29-rc0r4.4.29
(cherry picked from commit 4bf649ec51e337c143ce1fbebf77e64c27e8aa89)
(cherry picked from commit 5ff0b0748e945696b72f804f8d743bdceb0ddd18)
(cherry picked from commit 22f2f2951037466850adf762202c280a740d0328)
GitOrigin-RevId: f4dda329a99811c707eb06d05ad023599f9be263
| -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(); |
