summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jstests/replsets/retryable_writes_direct_write_to_config_transactions.js15
-rw-r--r--src/mongo/db/session.cpp5
-rw-r--r--src/mongo/db/session_catalog.h1
3 files changed, 18 insertions, 3 deletions
diff --git a/jstests/replsets/retryable_writes_direct_write_to_config_transactions.js b/jstests/replsets/retryable_writes_direct_write_to_config_transactions.js
index 0a89dcc7390..336cb0a8e2f 100644
--- a/jstests/replsets/retryable_writes_direct_write_to_config_transactions.js
+++ b/jstests/replsets/retryable_writes_direct_write_to_config_transactions.js
@@ -66,7 +66,20 @@
// the session to not work anymore for retryable writes for that session, but not for any other
const lsidManual = config.transactions.find({'_id.id': lsid1}).toArray()[0]._id;
assert.writeOK(config.transactions.remove({'_id.id': lsid1}));
- assert.writeOK(config.transactions.insert({_id: lsidManual}));
+
+ // Direct writes to the transactions table mark the session as killed and then asynchronously
+ // complete the cleanup process. Because of this, by the time the insert below starts, it is
+ // possible that the cleanup thread from the remove above has not yet completed and so the write
+ // could fail with ConflictingOperationInProgress.
+ assert.soon(function() {
+ try {
+ assert.writeOK(config.transactions.insert({_id: lsidManual}));
+ return true;
+ } catch (e) {
+ // assert.writeOK does not properly propagate the error code of the write error and
+ // because of this we cannot validate that the code is ConflictingOperationInProgress
+ }
+ });
const lsid3 = UUID();
assert.commandWorked(db.runCommand({
diff --git a/src/mongo/db/session.cpp b/src/mongo/db/session.cpp
index 3936dac0478..adbd165c267 100644
--- a/src/mongo/db/session.cpp
+++ b/src/mongo/db/session.cpp
@@ -45,7 +45,10 @@ OperationContext* Session::currentOperation() const {
Session::KillToken Session::kill(WithLock sessionCatalogLock, ErrorCodes::Error reason) {
stdx::lock_guard<stdx::mutex> lg(_mutex);
- uassert(ErrorCodes::ConflictingOperationInProgress, "Session already killed", !_killRequested);
+ uassert(ErrorCodes::ConflictingOperationInProgress,
+ str::stream() << "Session " << getSessionId().getId()
+ << " is already killed and is in the process of being cleaned up",
+ !_killRequested);
_killRequested = true;
// For currently checked-out sessions, interrupt the operation context so that the current owner
diff --git a/src/mongo/db/session_catalog.h b/src/mongo/db/session_catalog.h
index 90f44b3b60c..8e2a35d8b8d 100644
--- a/src/mongo/db/session_catalog.h
+++ b/src/mongo/db/session_catalog.h
@@ -251,7 +251,6 @@ class OperationContextSession {
public:
OperationContextSession(OperationContext* opCtx, bool checkOutSession);
-
~OperationContextSession();
/**