diff options
author | Siyuan Zhou <siyuan.zhou@mongodb.com> | 2019-03-20 18:32:59 -0400 |
---|---|---|
committer | Siyuan Zhou <siyuan.zhou@mongodb.com> | 2019-03-26 19:51:10 -0400 |
commit | 3aecf68d4b9cbdb3a9bde86bde945c733f50efe7 (patch) | |
tree | 766b7ef884e7fdfdaa5ad2417c7780bfa73379ab | |
parent | 6b5cfecb81da673a973415ada7c318865cf74153 (diff) | |
download | mongo-3aecf68d4b9cbdb3a9bde86bde945c733f50efe7.tar.gz |
SERVER-40081 Move session checkout to before command execution.
-rw-r--r-- | jstests/noPassthrough/currentop_active_transaction.js | 10 | ||||
-rw-r--r-- | jstests/noPassthrough/server_transaction_metrics.js | 8 | ||||
-rw-r--r-- | src/mongo/db/service_entry_point_common.cpp | 31 |
3 files changed, 20 insertions, 29 deletions
diff --git a/jstests/noPassthrough/currentop_active_transaction.js b/jstests/noPassthrough/currentop_active_transaction.js index 5f3ebab3547..019df41aeba 100644 --- a/jstests/noPassthrough/currentop_active_transaction.js +++ b/jstests/noPassthrough/currentop_active_transaction.js @@ -104,8 +104,6 @@ // This will make the transaction hang. assert.commandWorked(testDB.adminCommand( {configureFailPoint: 'hangAfterSettingPrepareStartTime', mode: 'alwaysOn'})); - assert.commandWorked( - testDB.adminCommand({setParameter: 1, internalQueryExecYieldIterations: 1})); let timeBeforeTransactionStarts = new ISODate(); let isPrepared = true; @@ -150,8 +148,8 @@ res = assert.commandWorked(testDB.runCommand({insert: collName, documents: [{x: 1}]})); // This will make the transaction hang. - assert.commandWorked(testDB.adminCommand( - {configureFailPoint: 'setInterruptOnlyPlansCheckForInterruptHang', mode: 'alwaysOn'})); + assert.commandWorked( + testDB.adminCommand({configureFailPoint: 'hangDuringBatchUpdate', mode: 'alwaysOn'})); timeBeforeTransactionStarts = new ISODate(); isPrepared = false; @@ -186,8 +184,8 @@ timeBeforeCurrentOp); // Now the transaction can proceed. - assert.commandWorked(testDB.adminCommand( - {configureFailPoint: 'setInterruptOnlyPlansCheckForInterruptHang', mode: 'off'})); + assert.commandWorked( + testDB.adminCommand({configureFailPoint: 'hangDuringBatchUpdate', mode: 'off'})); joinTransaction(); rst.stopSet(); diff --git a/jstests/noPassthrough/server_transaction_metrics.js b/jstests/noPassthrough/server_transaction_metrics.js index 1d437caba45..55c419aed0b 100644 --- a/jstests/noPassthrough/server_transaction_metrics.js +++ b/jstests/noPassthrough/server_transaction_metrics.js @@ -192,10 +192,8 @@ // inactive counters while operation is running inside a transaction. jsTest.log( "Start a transaction that will hang in the middle of an operation due to a fail point."); - assert.commandWorked(testDB.adminCommand( - {configureFailPoint: 'setInterruptOnlyPlansCheckForInterruptHang', mode: 'alwaysOn'})); assert.commandWorked( - testDB.adminCommand({setParameter: 1, internalQueryExecYieldIterations: 1})); + testDB.adminCommand({configureFailPoint: 'hangDuringBatchUpdate', mode: 'alwaysOn'})); const transactionFn = function() { const collName = 'server_transactions_metrics'; @@ -226,8 +224,8 @@ initialStatus.transactions, newStatus.transactions, "currentInactive", 0); // Now the transaction can proceed. - assert.commandWorked(testDB.adminCommand( - {configureFailPoint: 'setInterruptOnlyPlansCheckForInterruptHang', mode: 'off'})); + assert.commandWorked( + testDB.adminCommand({configureFailPoint: 'hangDuringBatchUpdate', mode: 'off'})); transactionProcess(); newStatus = assert.commandWorked(testDB.adminCommand({serverStatus: 1})); verifyServerStatusFields(newStatus); diff --git a/src/mongo/db/service_entry_point_common.cpp b/src/mongo/db/service_entry_point_common.cpp index 8d7d9a71ee7..279962bb37f 100644 --- a/src/mongo/db/service_entry_point_common.cpp +++ b/src/mongo/db/service_entry_point_common.cpp @@ -373,9 +373,14 @@ void appendClusterAndOperationTime(OperationContext* opCtx, void invokeWithSessionCheckedOut(OperationContext* opCtx, CommandInvocation* invocation, - TransactionParticipant::Participant txnParticipant, const OperationSessionInfoFromClient& sessionOptions, rpc::ReplyBuilderInterface* replyBuilder) { + // This constructor will check out the session. It handles the appropriate state management + // for both multi-statement transactions and retryable writes. Currently, only requests with + // a transaction number will check out the session. + MongoDOperationContextSession sessionTxnState(opCtx); + auto txnParticipant = TransactionParticipant::get(opCtx); + if (!opCtx->getClient()->isInDirectClient()) { txnParticipant.beginOrContinue(opCtx, *sessionOptions.getTxnNumber(), @@ -469,12 +474,13 @@ bool runCommandImpl(OperationContext* opCtx, #endif replyBuilder->reserveBytes(bytesToReserve); - auto txnParticipant = TransactionParticipant::get(opCtx); + const bool shouldCheckOutSession = + sessionOptions.getTxnNumber() && !shouldCommandSkipSessionCheckout(command->getName()); + if (!invocation->supportsWriteConcern()) { behaviors.uassertCommandDoesNotSpecifyWriteConcern(request.body); - if (txnParticipant) { - invokeWithSessionCheckedOut( - opCtx, invocation, txnParticipant, sessionOptions, replyBuilder); + if (shouldCheckOutSession) { + invokeWithSessionCheckedOut(opCtx, invocation, sessionOptions, replyBuilder); } else { invocation->run(opCtx, replyBuilder); MONGO_FAIL_POINT_BLOCK(waitAfterReadCommandFinishesExecution, options) { @@ -515,9 +521,8 @@ bool runCommandImpl(OperationContext* opCtx, }; try { - if (txnParticipant) { - invokeWithSessionCheckedOut( - opCtx, invocation, txnParticipant, sessionOptions, replyBuilder); + if (shouldCheckOutSession) { + invokeWithSessionCheckedOut(opCtx, invocation, sessionOptions, replyBuilder); } else { invocation->run(opCtx, replyBuilder); } @@ -619,16 +624,6 @@ void execCommandDatabase(OperationContext* opCtx, validateSessionOptions(sessionOptions, command->getName(), dbname); - // This constructor will check out the session and start a transaction, if necessary. It - // handles the appropriate state management for both multi-statement transactions and - // retryable writes. Currently, only requests with a transaction number will check out the - // session. - boost::optional<MongoDOperationContextSession> sessionTxnState; - const bool shouldCheckOutSession = - sessionOptions.getTxnNumber() && !shouldCommandSkipSessionCheckout(command->getName()); - if (shouldCheckOutSession) - sessionTxnState.emplace(opCtx); - std::unique_ptr<MaintenanceModeSetter> mmSetter; BSONElement cmdOptionMaxTimeMSField; |