summaryrefslogtreecommitdiff
path: root/src/mongo/db/session.cpp
diff options
context:
space:
mode:
authorSpencer T Brody <spencer@mongodb.com>2018-08-15 18:10:03 -0400
committerSpencer T Brody <spencer@mongodb.com>2018-08-22 18:29:06 -0400
commitb313d4dc086c039af423cdf4bdf25b9091455ce5 (patch)
tree26a5b477ad7c129cf9f6fb0d683983682d703bd5 /src/mongo/db/session.cpp
parentd8810253bff426c58ee9040689302f8964053c9c (diff)
downloadmongo-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.cpp38
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);
}