diff options
author | Matthew Saltz <matthew.saltz@mongodb.com> | 2018-09-14 18:31:31 -0400 |
---|---|---|
committer | Matthew Saltz <matthew.saltz@mongodb.com> | 2018-10-04 13:40:32 -0400 |
commit | 7eba85974ac533a5ad99babe8909375277c01328 (patch) | |
tree | fc2dc38f4eebb8d0d663acc3c4ec1013aa4cfa62 /src/mongo/db/s | |
parent | 33df3d3c8da6b75913cdf7c04b60f6d85cdc5cf4 (diff) | |
download | mongo-7eba85974ac533a5ad99babe8909375277c01328.tar.gz |
SERVER-37363 Return Future with commit decision from coordinateCommit
Diffstat (limited to 'src/mongo/db/s')
-rw-r--r-- | src/mongo/db/s/txn_two_phase_commit_cmds.cpp | 23 |
1 files changed, 19 insertions, 4 deletions
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 768bdaad4c6..0cc017ac341 100644 --- a/src/mongo/db/s/txn_two_phase_commit_cmds.cpp +++ b/src/mongo/db/s/txn_two_phase_commit_cmds.cpp @@ -331,6 +331,7 @@ public: } } voteAbortTransactionCmd; +// TODO (SERVER-37440): Make coordinateCommit idempotent. class CoordinateCommitTransactionCmd : public TypedCommand<CoordinateCommitTransactionCmd> { public: using Request = CoordinateCommitTransaction; @@ -365,15 +366,29 @@ public: participantList.insert(shardId); } - TransactionCoordinatorService::get(opCtx)->coordinateCommit( + auto commitDecisionFuture = TransactionCoordinatorService::get(opCtx)->coordinateCommit( opCtx, opCtx->getLogicalSessionId().get(), opCtx->getTxnNumber().get(), participantList); - // Execute the 'prepare' logic on the local participant (the router does not send a - // separate 'prepare' message to the coordinator shard). - _callPrepareOnLocalParticipant(opCtx); + // If the commit decision is already available before we prepare locally, it means the + // transaction has completed and we should skip preparing locally. + // + // TODO (SERVER-37440): Reconsider when coordinateCommit is made idempotent. + if (!commitDecisionFuture.isReady()) { + // Execute the 'prepare' logic on the local participant (the router does not send a + // separate 'prepare' message to the coordinator shard). + _callPrepareOnLocalParticipant(opCtx); + } + + // Block waiting for the commit decision. + auto commitDecision = commitDecisionFuture.get(opCtx); + + // If the decision was abort, propagate NoSuchTransaction exception back to mongos. + uassert(ErrorCodes::NoSuchTransaction, + "Transaction was aborted", + commitDecision != TransactionCoordinatorService::CommitDecision::kAbort); } private: |