diff options
author | Spencer T Brody <spencer@mongodb.com> | 2018-08-15 18:10:03 -0400 |
---|---|---|
committer | Spencer T Brody <spencer@mongodb.com> | 2018-08-22 18:29:06 -0400 |
commit | b313d4dc086c039af423cdf4bdf25b9091455ce5 (patch) | |
tree | 26a5b477ad7c129cf9f6fb0d683983682d703bd5 /src/mongo/db/session.cpp | |
parent | d8810253bff426c58ee9040689302f8964053c9c (diff) | |
download | mongo-b313d4dc086c039af423cdf4bdf25b9091455ce5.tar.gz |
SERVER-36331 Kill running op when a transaction expires
(cherry picked from commit b83c5312dc5f437480de10487f945933a96a7ccd)
Diffstat (limited to 'src/mongo/db/session.cpp')
-rw-r--r-- | src/mongo/db/session.cpp | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/src/mongo/db/session.cpp b/src/mongo/db/session.cpp index 83139595f53..8537513bd28 100644 --- a/src/mongo/db/session.cpp +++ b/src/mongo/db/session.cpp @@ -292,6 +292,18 @@ const BSONObj Session::kDeadEndSentinel(BSON("$incompleteOplogHistory" << 1)); Session::Session(LogicalSessionId sessionId) : _sessionId(std::move(sessionId)) {} +void Session::setCurrentOperation(OperationContext* currentOperation) { + stdx::lock_guard<stdx::mutex> lk(_mutex); + invariant(!_currentOperation); + _currentOperation = currentOperation; +} + +void Session::clearCurrentOperation() { + stdx::lock_guard<stdx::mutex> lk(_mutex); + invariant(_currentOperation); + _currentOperation = nullptr; +} + void Session::refreshFromStorageIfNeeded(OperationContext* opCtx) { if (opCtx->getClient()->isInDirectClient()) { return; @@ -838,22 +850,34 @@ void Session::unstashTransactionResources(OperationContext* opCtx, const std::st void Session::abortArbitraryTransaction() { stdx::lock_guard<stdx::mutex> lock(_mutex); - _abortArbitraryTransaction(lock); + + if (_txnState != MultiDocumentTransactionState::kInProgress) { + return; + } + + _abortTransaction(lock); } void Session::abortArbitraryTransactionIfExpired() { stdx::lock_guard<stdx::mutex> lock(_mutex); - if (!_transactionExpireDate || _transactionExpireDate >= Date_t::now()) { + if (_txnState != MultiDocumentTransactionState::kInProgress || !_transactionExpireDate || + _transactionExpireDate >= Date_t::now()) { return; } - _abortArbitraryTransaction(lock); -} -void Session::_abortArbitraryTransaction(WithLock lock) { - if (_txnState != MultiDocumentTransactionState::kInProgress) { - return; + if (_currentOperation) { + // If an operation is still running for this transaction when it expires, kill the currently + // running operation. + stdx::lock_guard<Client> clientLock(*_currentOperation->getClient()); + getGlobalServiceContext()->killOperation(_currentOperation, ErrorCodes::ExceededTimeLimit); } + // Log after killing the current operation because jstests may wait to see this log message to + // imply that the operation has been killed. + log() << "Aborting transaction with txnNumber " << _activeTxnNumber << " on session with lsid " + << _sessionId.getId() + << " because it has been running for longer than 'transactionLifetimeLimitSeconds'"; + _abortTransaction(lock); } |