summaryrefslogtreecommitdiff
path: root/src/mongo/db/transaction_participant.cpp
diff options
context:
space:
mode:
authorVesselina Ratcheva <vesselina.ratcheva@10gen.com>2019-02-20 13:42:23 -0500
committerVesselina Ratcheva <vesselina.ratcheva@10gen.com>2019-02-26 14:57:59 -0500
commit58fad7d7efa275beb4a6a83f90d3dd222bbb534b (patch)
tree8dc0537629d4d7ec2ebed0b582c6f60838efe5dc /src/mongo/db/transaction_participant.cpp
parente61f7582788f51b2287f179c8f27ec8fa41744f7 (diff)
downloadmongo-58fad7d7efa275beb4a6a83f90d3dd222bbb534b.tar.gz
SERVER-39139 Disallow starting transactions on secondaries
Diffstat (limited to 'src/mongo/db/transaction_participant.cpp')
-rw-r--r--src/mongo/db/transaction_participant.cpp11
1 files changed, 11 insertions, 0 deletions
diff --git a/src/mongo/db/transaction_participant.cpp b/src/mongo/db/transaction_participant.cpp
index 2d3127323b8..2a7e6817328 100644
--- a/src/mongo/db/transaction_participant.cpp
+++ b/src/mongo/db/transaction_participant.cpp
@@ -446,6 +446,17 @@ void TransactionParticipant::Participant::beginOrContinue(OperationContext* opCt
TxnNumber txnNumber,
boost::optional<bool> autocommit,
boost::optional<bool> startTransaction) {
+ // Make sure we are still a primary. We need to hold on to the RSTL through the end of this
+ // method, as we otherwise risk stepping down in the interim and incorrectly updating the
+ // transaction number, which can abort active transactions.
+ Lock::ResourceLock rstl(opCtx->lockState(), resourceIdReplicationStateTransitionLock, MODE_IX);
+ if (opCtx->writesAreReplicated()) {
+ auto replCoord = repl::ReplicationCoordinator::get(opCtx);
+ uassert(ErrorCodes::NotMaster,
+ "Not primary so we cannot begin or continue a transaction",
+ replCoord->canAcceptWritesForDatabase(opCtx, "admin"));
+ }
+
uassert(ErrorCodes::TransactionTooOld,
str::stream() << "Cannot start transaction " << txnNumber << " on session "
<< _sessionId()