diff options
author | Jennifer Peshansky <jennifer.peshansky@mongodb.com> | 2022-11-03 16:13:20 +0000 |
---|---|---|
committer | Jennifer Peshansky <jennifer.peshansky@mongodb.com> | 2022-11-03 16:13:20 +0000 |
commit | e74d2910bbe76790ad131d53fee277829cd95982 (patch) | |
tree | cabe148764529c9623652374fbc36323a550cd44 /src/mongo/db/transaction/transaction_api.cpp | |
parent | 280145e9940729480bb8a35453d4056afac87641 (diff) | |
parent | ba467f46cc1bc49965e1d72b541eff0cf1d7b22e (diff) | |
download | mongo-jenniferpeshansky/SERVER-70854.tar.gz |
Merge branch 'master' into jenniferpeshansky/SERVER-70854jenniferpeshansky/SERVER-70854
Diffstat (limited to 'src/mongo/db/transaction/transaction_api.cpp')
-rw-r--r-- | src/mongo/db/transaction/transaction_api.cpp | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/src/mongo/db/transaction/transaction_api.cpp b/src/mongo/db/transaction/transaction_api.cpp index 36635d16694..1150c5b5750 100644 --- a/src/mongo/db/transaction/transaction_api.cpp +++ b/src/mongo/db/transaction/transaction_api.cpp @@ -300,17 +300,32 @@ SemiFuture<BSONObj> SEPTransactionClient::runCommand(StringData dbName, BSONObj BSONObjBuilder cmdBuilder(_behaviors->maybeModifyCommand(std::move(cmdObj))); _hooks->runRequestHook(&cmdBuilder); + auto modifiedCmdObj = cmdBuilder.obj(); + bool isAbortTxnCmd = modifiedCmdObj.firstElementFieldNameStringData() == "abortTransaction"; auto client = _serviceContext->makeClient("SEP-internal-txn-client"); AlternativeClientRegion clientRegion(client); + // Note that _token is only cancelled once the caller of the transaction no longer cares about // its result, so CancelableOperationContexts only being interrupted by ErrorCodes::Interrupted - // shouldn't impact any upstream retry logic. - CancelableOperationContextFactory opCtxFactory(_token, _executor); + // shouldn't impact any upstream retry logic. If a _bestEffortAbort() is invoked, a new + // cancelation token must be used in constructing the opCtx for running abortTransaction. This + // is because an operation that has already been interrupted would cancel the parent cancelation + // token and using that same token to send abortTransaction would fail to send abortTransaction, + // leaving the transaction open longer than necessary. + auto opCtxFactory = isAbortTxnCmd + ? CancelableOperationContextFactory(CancellationToken::uncancelable(), _executor) + : CancelableOperationContextFactory(_token, _executor); + auto cancellableOpCtx = opCtxFactory.makeOperationContext(&cc()); + + // abortTransaction should still be interruptible on stepdown/shutdown. + if (isAbortTxnCmd) { + cancellableOpCtx->setAlwaysInterruptAtStepDownOrUp_UNSAFE(); + } primeInternalClient(&cc()); - auto opMsgRequest = OpMsgRequest::fromDBAndBody(dbName, cmdBuilder.obj()); + auto opMsgRequest = OpMsgRequest::fromDBAndBody(dbName, modifiedCmdObj); auto requestMessage = opMsgRequest.serialize(); return _behaviors->handleRequest(cancellableOpCtx.get(), requestMessage) .then([this](DbResponse dbResponse) { |