summaryrefslogtreecommitdiff
path: root/src/mongo/db/s
diff options
context:
space:
mode:
authorMatthew Saltz <matthew.saltz@mongodb.com>2018-09-14 18:31:31 -0400
committerMatthew Saltz <matthew.saltz@mongodb.com>2018-10-04 13:40:32 -0400
commit7eba85974ac533a5ad99babe8909375277c01328 (patch)
treefc2dc38f4eebb8d0d663acc3c4ec1013aa4cfa62 /src/mongo/db/s
parent33df3d3c8da6b75913cdf7c04b60f6d85cdc5cf4 (diff)
downloadmongo-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.cpp23
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: