diff options
author | Jack Mulrow <jack.mulrow@mongodb.com> | 2018-09-28 11:37:11 -0400 |
---|---|---|
committer | Jack Mulrow <jack.mulrow@mongodb.com> | 2018-10-09 09:39:08 -0400 |
commit | 3dc5e5979bc9a4a914b0a479e88e70078bd02552 (patch) | |
tree | cf79737a7d466d238dd2769960ddc7690befb86b /src/mongo/s/transaction_router.cpp | |
parent | f2254e26b9c7bdd94e4e6613ef5a20302ecc855e (diff) | |
download | mongo-3dc5e5979bc9a4a914b0a479e88e70078bd02552.tar.gz |
SERVER-37223 Invariant sharded txns with snapshot read concern select atClusterTime before creating a participant
Diffstat (limited to 'src/mongo/s/transaction_router.cpp')
-rw-r--r-- | src/mongo/s/transaction_router.cpp | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/src/mongo/s/transaction_router.cpp b/src/mongo/s/transaction_router.cpp index 013f212148d..30a6c0054f1 100644 --- a/src/mongo/s/transaction_router.cpp +++ b/src/mongo/s/transaction_router.cpp @@ -281,6 +281,25 @@ BSONObj TransactionRouter::attachTxnFieldsIfNeeded(const ShardId& shardId, const return txnPart.attachTxnFieldsIfNeeded(cmdObj, true); } +void TransactionRouter::_verifyReadConcern() { + invariant(!_readConcernArgs.isEmpty()); + + if (_readConcernArgs.getLevel() == repl::ReadConcernLevel::kSnapshotReadConcern) { + invariant(_atClusterTime); + invariant(_atClusterTime != LogicalTime::kUninitialized); + } +} + +void TransactionRouter::_verifyParticipantAtClusterTime(const Participant& participant) { + if (_readConcernArgs.getLevel() != repl::ReadConcernLevel::kSnapshotReadConcern) { + return; + } + + auto participantAtClusterTime = participant.getSharedOptions().atClusterTime; + invariant(participantAtClusterTime); + invariant(participantAtClusterTime == _atClusterTime); +} + boost::optional<TransactionRouter::Participant&> TransactionRouter::getParticipant( const ShardId& shard) { auto iter = _participants.find(shard.toString()); @@ -288,9 +307,9 @@ boost::optional<TransactionRouter::Participant&> TransactionRouter::getParticipa return boost::none; } - // TODO SERVER-37223: Once mongos aborts transactions by only sending abortTransaction to - // shards that have been successfully contacted we should be able to add an invariant here - // to ensure the atClusterTime on the participant matches that on the transaction router. + _verifyReadConcern(); + _verifyParticipantAtClusterTime(iter->second); + return iter->second; } @@ -302,12 +321,7 @@ TransactionRouter::Participant& TransactionRouter::_createParticipant(const Shar _coordinatorId = shard.toString(); } - // The transaction must have been started with a readConcern. - invariant(!_readConcernArgs.isEmpty()); - - // TODO SERVER-37223: Once mongos aborts transactions by only sending abortTransaction to shards - // that have been successfully contacted we should be able to add an invariant here to ensure - // that an atClusterTime has been chosen if the read concern level is snapshot. + _verifyReadConcern(); auto resultPair = _participants.try_emplace( shard.toString(), |