diff options
-rw-r--r-- | jstests/replsets/retryable_writes_direct_write_to_config_transactions.js | 15 | ||||
-rw-r--r-- | src/mongo/db/session.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/session_catalog.h | 1 |
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(); /** |