commit af24bc3ae505391add182bfc95449d7f9f1ed6ff Author: A. Jesse Jiryu Davis Date: Sat Feb 16 17:24:58 2019 -0500 fix side transaction diff --git a/src/mongo/db/transaction_participant.cpp b/src/mongo/db/transaction_participant.cpp index b484d0fc07..8421a68362 100644 --- a/src/mongo/db/transaction_participant.cpp +++ b/src/mongo/db/transaction_participant.cpp @@ -685,6 +685,11 @@ TransactionParticipant::SideTransactionBlock::SideTransactionBlock(OperationCont _txnResources = TransactionParticipant::TxnResources( _opCtx, TxnResources::StashStyle::kSideTransaction); } + + auto txnParticipant = TransactionParticipant::get(opCtx); + if (txnParticipant) { + txnParticipant->pushSideTransactionBlock(); + } } TransactionParticipant::SideTransactionBlock::~SideTransactionBlock() { @@ -692,7 +697,13 @@ TransactionParticipant::SideTransactionBlock::~SideTransactionBlock() { // Restore the transaction state onto '_opCtx'. _txnResources->release(_opCtx); } + + auto txnParticipant = TransactionParticipant::get(_opCtx); + if (txnParticipant) { + txnParticipant->popSideTransactionBlock(); + } } + void TransactionParticipant::_stashActiveTransaction(WithLock, OperationContext* opCtx) { if (_inShutdown) { return; @@ -990,6 +1001,11 @@ void TransactionParticipant::addTransactionOperation(OperationContext* opCtx, const repl::ReplOperation& operation) { stdx::lock_guard lk(_mutex); + if (_sideTransactionBlocks) { + // This operation is in a side transaction. + return; + } + // Always check _getSession()'s txnNumber and '_txnState', since they can be modified by session // kill and migration, which do not check out the session. _checkIsActiveTransaction(lk, *opCtx->getTxnNumber(), true); diff --git a/src/mongo/db/transaction_participant.h b/src/mongo/db/transaction_participant.h index 650e1296f6..ae571e065f 100644 --- a/src/mongo/db/transaction_participant.h +++ b/src/mongo/db/transaction_participant.h @@ -501,6 +501,22 @@ public: */ void reportUnstashedState(OperationContext* opCtx, BSONObjBuilder* builder) const; + /** + * Called by SideTransactionBlock to inform the transaction participant that a block began. + * Not thread-safe. + */ + void pushSideTransactionBlock() { + ++_sideTransactionBlocks; + } + + /** + * Called by SideTransactionBlock to inform the transaction participant that a block ended. + * Not thread-safe. + */ + void popSideTransactionBlock() { + --_sideTransactionBlocks; + } + // // Methods used for unit-testing only // @@ -891,6 +907,8 @@ private: // opTime. Used for fast retryability check and retrieving the previous write's data without // having to scan through the oplog. CommittedStatementTimestampMap _activeTxnCommittedStatements; + + int _sideTransactionBlocks = 0; }; } // namespace mongo