summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSiyuan Zhou <siyuan.zhou@mongodb.com>2019-03-20 18:32:59 -0400
committerSiyuan Zhou <siyuan.zhou@mongodb.com>2019-03-26 19:51:10 -0400
commit3aecf68d4b9cbdb3a9bde86bde945c733f50efe7 (patch)
tree766b7ef884e7fdfdaa5ad2417c7780bfa73379ab
parent6b5cfecb81da673a973415ada7c318865cf74153 (diff)
downloadmongo-3aecf68d4b9cbdb3a9bde86bde945c733f50efe7.tar.gz
SERVER-40081 Move session checkout to before command execution.
-rw-r--r--jstests/noPassthrough/currentop_active_transaction.js10
-rw-r--r--jstests/noPassthrough/server_transaction_metrics.js8
-rw-r--r--src/mongo/db/service_entry_point_common.cpp31
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;