summaryrefslogtreecommitdiff
path: root/src/mongo/db/transaction_participant.cpp
diff options
context:
space:
mode:
authorVesselina Ratcheva <vesselina.ratcheva@10gen.com>2019-05-24 17:22:30 -0400
committerVesselina Ratcheva <vesselina.ratcheva@10gen.com>2019-05-29 13:05:21 -0400
commitcb45824b458c1b3714a379c5c658e1e89238c03d (patch)
treec4e080a13ee892672dd6dc33476be9aad89532cc /src/mongo/db/transaction_participant.cpp
parente11c234484fe58681597ba74fd23fa76de734250 (diff)
downloadmongo-cb45824b458c1b3714a379c5c658e1e89238c03d.tar.gz
SERVER-41317 Push commit transaction's check for a majority-committed prepare down into the TransactionParticipant
Diffstat (limited to 'src/mongo/db/transaction_participant.cpp')
-rw-r--r--src/mongo/db/transaction_participant.cpp19
1 files changed, 17 insertions, 2 deletions
diff --git a/src/mongo/db/transaction_participant.cpp b/src/mongo/db/transaction_participant.cpp
index 3b963c9d7b8..0ccc127e94d 100644
--- a/src/mongo/db/transaction_participant.cpp
+++ b/src/mongo/db/transaction_participant.cpp
@@ -81,6 +81,8 @@ MONGO_FAIL_POINT_DEFINE(hangAfterSettingPrepareStartTime);
MONGO_FAIL_POINT_DEFINE(hangBeforeReleasingTransactionOplogHole);
+MONGO_FAIL_POINT_DEFINE(skipCommitTxnCheckPrepareMajorityCommitted);
+
const auto getTransactionParticipant = Session::declareDecoration<TransactionParticipant>();
// The command names that are allowed in a prepared transaction.
@@ -1260,8 +1262,10 @@ void TransactionParticipant::Participant::commitPreparedTransaction(
// transaction was prepared, we dropped the RSTL. We do not need to reacquire the PBWM because
// if we're not the primary we will uassert anyways.
repl::ReplicationStateTransitionLockGuard rstl(opCtx, MODE_IX);
+
+ const auto replCoord = repl::ReplicationCoordinator::get(opCtx);
+
if (opCtx->writesAreReplicated()) {
- auto replCoord = repl::ReplicationCoordinator::get(opCtx);
uassert(ErrorCodes::NotMaster,
"Not primary so we cannot commit a prepared transaction",
replCoord->canAcceptWritesForDatabase(opCtx, "admin"));
@@ -1272,9 +1276,20 @@ void TransactionParticipant::Participant::commitPreparedTransaction(
o().txnState.isPrepared());
uassert(
ErrorCodes::InvalidOptions, "'commitTimestamp' cannot be null", !commitTimestamp.isNull());
+
+ const auto prepareTimestamp = o().prepareOpTime.getTimestamp();
+
uassert(ErrorCodes::InvalidOptions,
"'commitTimestamp' must be greater than or equal to 'prepareTimestamp'",
- commitTimestamp >= o().prepareOpTime.getTimestamp());
+ commitTimestamp >= prepareTimestamp);
+
+ if (!commitOplogEntryOpTime) {
+ uassert(ErrorCodes::InvalidOptions,
+ "commitTransaction for a prepared transaction cannot be run before its prepare "
+ "oplog entry has been majority committed",
+ replCoord->getLastCommittedOpTime().getTimestamp() >= prepareTimestamp ||
+ MONGO_FAIL_POINT(skipCommitTxnCheckPrepareMajorityCommitted));
+ }
{
stdx::lock_guard<Client> lk(*opCtx->getClient());