diff options
author | Siyuan Zhou <siyuan.zhou@mongodb.com> | 2018-10-10 21:10:05 -0400 |
---|---|---|
committer | Siyuan Zhou <siyuan.zhou@mongodb.com> | 2018-10-24 20:19:20 -0400 |
commit | 248601a6473fc7364e5d790a357acbace2a42f7a (patch) | |
tree | ca3b954d14757df9c41802038ff9086c6ab66037 | |
parent | 887cc3f6db2a15d94e8ae2195d8183f16337d926 (diff) | |
download | mongo-248601a6473fc7364e5d790a357acbace2a42f7a.tar.gz |
SERVER-37179 Pass the reference of OperationSessionInfoFromClient around.
20 files changed, 267 insertions, 239 deletions
diff --git a/jstests/core/txns/commands_not_allowed_in_txn.js b/jstests/core/txns/commands_not_allowed_in_txn.js index e2c1cc23e78..44eb038caf5 100644 --- a/jstests/core/txns/commands_not_allowed_in_txn.js +++ b/jstests/core/txns/commands_not_allowed_in_txn.js @@ -146,7 +146,7 @@ stmtId: NumberInt(1), autocommit: false }), - ErrorCodes.ConflictingOperationInProgress); + ErrorCodes.OperationNotSupportedInTransaction); // It is still possible to commit the transaction. The rejected command does not abort the // transaction. diff --git a/jstests/core/txns/disallow_operations_on_prepared_transaction.js b/jstests/core/txns/disallow_operations_on_prepared_transaction.js index 9e02f4ddbb9..8888684fb46 100644 --- a/jstests/core/txns/disallow_operations_on_prepared_transaction.js +++ b/jstests/core/txns/disallow_operations_on_prepared_transaction.js @@ -71,7 +71,7 @@ stmtId: NumberInt(1), autocommit: false }), - ErrorCodes.ConflictingOperationInProgress); + ErrorCodes.OperationNotSupportedInTransaction); jsTestLog("Test that you can't run find on a prepared transaction."); assert.commandFailedWithCode(assert.throws(function() { diff --git a/jstests/core/txns/do_txn_basic.js b/jstests/core/txns/do_txn_basic.js index 7e9bd4b98e1..de753f787dc 100644 --- a/jstests/core/txns/do_txn_basic.js +++ b/jstests/core/txns/do_txn_basic.js @@ -86,7 +86,10 @@ jsTestLog("Valid 'ns' field value in unknown operation type 'x'."); assert.commandFailedWithCode( - db.adminCommand({doTxn: [{op: 'x', ns: t.getFullName(), o: {_id: 0}}]}), + db.adminCommand({ + doTxn: [{op: 'x', ns: t.getFullName(), o: {_id: 0}}], + txnNumber: NumberLong(txnNumber++) + }), ErrorCodes.FailedToParse, 'doTxn should fail on unknown operation type "x" with valid "ns" value'); @@ -159,10 +162,12 @@ 'doTxn should fail when inner transaction contains statement id.'); jsTestLog("Malformed operation with unexpected field 'x'."); - assert.commandFailedWithCode( - db.adminCommand({doTxn: [{op: 'i', ns: t.getFullName(), o: {_id: 0}, x: 1}]}), - ErrorCodes.FailedToParse, - 'doTxn should fail on malformed operations.'); + assert.commandFailedWithCode(db.adminCommand({ + doTxn: [{op: 'i', ns: t.getFullName(), o: {_id: 0}, x: 1}], + txnNumber: NumberLong(txnNumber++) + }), + ErrorCodes.FailedToParse, + 'doTxn should fail on malformed operations.'); assert.eq(0, t.find().count(), "Non-zero amount of documents in collection to start"); diff --git a/src/mongo/db/commands/do_txn_cmd.cpp b/src/mongo/db/commands/do_txn_cmd.cpp index d09a28389b3..386368467a3 100644 --- a/src/mongo/db/commands/do_txn_cmd.cpp +++ b/src/mongo/db/commands/do_txn_cmd.cpp @@ -118,6 +118,14 @@ public: return true; } + bool supportsReadConcern(const std::string& dbName, + const BSONObj& cmdObj, + repl::ReadConcernLevel level) const { + // Support the read concerns before and after upconversion. + return level == repl::ReadConcernLevel::kLocalReadConcern || + level == repl::ReadConcernLevel::kSnapshotReadConcern; + } + std::string help() const override { return "internal (sharding)\n{ doTxn : [ ] , preCondition : [ { ns : ... , q : ... , " "res : ... } ] }"; diff --git a/src/mongo/db/handle_request_response.cpp b/src/mongo/db/handle_request_response.cpp index 2b77eea7a95..717b44ba2f4 100644 --- a/src/mongo/db/handle_request_response.cpp +++ b/src/mongo/db/handle_request_response.cpp @@ -32,11 +32,12 @@ namespace mongo { -BSONObj getErrorLabels(const boost::optional<OperationSessionInfoFromClient>& sessionOptions, +BSONObj getErrorLabels(const OperationSessionInfoFromClient& sessionOptions, const std::string& commandName, ErrorCodes::Error code) { // By specifying "autocommit", the user indicates they want to run a transaction. - if (!sessionOptions || !sessionOptions->getAutocommit()) { + // It is always false when set. + if (!sessionOptions.getAutocommit()) { return {}; } diff --git a/src/mongo/db/handle_request_response.h b/src/mongo/db/handle_request_response.h index 65682042449..67d4f62be44 100644 --- a/src/mongo/db/handle_request_response.h +++ b/src/mongo/db/handle_request_response.h @@ -37,7 +37,7 @@ namespace mongo { /** * Returns the error labels for the given error. */ -BSONObj getErrorLabels(const boost::optional<OperationSessionInfoFromClient>& sessionOptions, +BSONObj getErrorLabels(const OperationSessionInfoFromClient& sessionOptions, const std::string& commandName, ErrorCodes::Error code); diff --git a/src/mongo/db/initialize_operation_session_info.cpp b/src/mongo/db/initialize_operation_session_info.cpp index a7f4b003499..e513126f173 100644 --- a/src/mongo/db/initialize_operation_session_info.cpp +++ b/src/mongo/db/initialize_operation_session_info.cpp @@ -40,12 +40,11 @@ namespace mongo { -boost::optional<OperationSessionInfoFromClient> initializeOperationSessionInfo( - OperationContext* opCtx, - const BSONObj& requestBody, - bool requiresAuth, - bool isReplSetMemberOrMongos, - bool supportsDocLocking) { +OperationSessionInfoFromClient initializeOperationSessionInfo(OperationContext* opCtx, + const BSONObj& requestBody, + bool requiresAuth, + bool isReplSetMemberOrMongos, + bool supportsDocLocking) { auto osi = OperationSessionInfoFromClient::parse("OperationSessionInfo"_sd, requestBody); if (opCtx->getClient()->isInDirectClient()) { @@ -61,7 +60,7 @@ boost::optional<OperationSessionInfoFromClient> initializeOperationSessionInfo( !osi.getAutocommit()); uassert( 50889, "It is illegal to provide a txnNumber for this command", !osi.getTxnNumber()); - return boost::none; + return {}; } { @@ -71,7 +70,7 @@ boost::optional<OperationSessionInfoFromClient> initializeOperationSessionInfo( AuthorizationSession* authSession = AuthorizationSession::get(opCtx->getClient()); if (authSession && authSession->isUsingLocalhostBypass() && !authSession->isAuthenticated()) { - return boost::none; + return {}; } } @@ -82,7 +81,7 @@ boost::optional<OperationSessionInfoFromClient> initializeOperationSessionInfo( if (!lsc) { // Ignore session information if the logical session cache has not been set up, e.g. on // the embedded version of mongod. - return boost::none; + return {}; } opCtx->setLogicalSessionId(makeLogicalSessionId(osi.getSessionId().get(), opCtx)); @@ -133,6 +132,22 @@ boost::optional<OperationSessionInfoFromClient> initializeOperationSessionInfo( osi.getStartTransaction().value()); } + // Populate the session info for doTxn command. + if (requestBody.firstElementFieldName() == "doTxn"_sd) { + uassert(ErrorCodes::InvalidOptions, + "doTxn can only be run with a transaction number.", + osi.getTxnNumber()); + uassert(ErrorCodes::OperationNotSupportedInTransaction, + "doTxn can not be run in a transaction", + !osi.getAutocommit()); + // 'autocommit' and 'startTransaction' are populated for 'doTxn' to get the oplog + // entry generation behavior used for multi-document transactions. The 'doTxn' + // command still logically behaves as a commit. + osi.setAutocommit(false); + osi.setStartTransaction(true); + } + + return osi; } diff --git a/src/mongo/db/initialize_operation_session_info.h b/src/mongo/db/initialize_operation_session_info.h index d7d99e95736..10c5953c557 100644 --- a/src/mongo/db/initialize_operation_session_info.h +++ b/src/mongo/db/initialize_operation_session_info.h @@ -47,15 +47,11 @@ namespace mongo { * * Both isReplSetMemberOrMongos and supportsDocLocking need to be true if the command contains a * transaction number, otherwise this function will throw. - * - * On success, returns the parsed request information. Returning boost::none implies that the - * proper command or session requirements were not met. */ -boost::optional<OperationSessionInfoFromClient> initializeOperationSessionInfo( - OperationContext* opCtx, - const BSONObj& requestBody, - bool requiresAuth, - bool isReplSetMemberOrMongos, - bool supportsDocLocking); +OperationSessionInfoFromClient initializeOperationSessionInfo(OperationContext* opCtx, + const BSONObj& requestBody, + bool requiresAuth, + bool isReplSetMemberOrMongos, + bool supportsDocLocking); } // namespace mongo diff --git a/src/mongo/db/logical_session_id_test.cpp b/src/mongo/db/logical_session_id_test.cpp index 5a4d14705ac..1bf9e9b4658 100644 --- a/src/mongo/db/logical_session_id_test.cpp +++ b/src/mongo/db/logical_session_id_test.cpp @@ -335,13 +335,17 @@ TEST_F(LogicalSessionIdTest, InitializeOperationSessionInfo_IgnoresInfoIfNoCache LogicalSessionCache::set(_opCtx->getServiceContext(), nullptr); - ASSERT_FALSE(initializeOperationSessionInfo( + auto sessionInfo = initializeOperationSessionInfo( _opCtx.get(), BSON("TestCmd" << 1 << "lsid" << lsid.toBSON() << "txnNumber" << 100LL << "OtherField" << "TestField"), true, true, - true)); + true); + ASSERT(sessionInfo.getSessionId() == boost::none); + ASSERT(sessionInfo.getTxnNumber() == boost::none); + ASSERT(sessionInfo.getStartTransaction() == boost::none); + ASSERT(sessionInfo.getAutocommit() == boost::none); } TEST_F(LogicalSessionIdTest, InitializeOperationSessionInfo_SendingInfoFailsInDirectClient) { diff --git a/src/mongo/db/op_observer_impl_test.cpp b/src/mongo/db/op_observer_impl_test.cpp index f10b89a8f71..832413c3482 100644 --- a/src/mongo/db/op_observer_impl_test.cpp +++ b/src/mongo/db/op_observer_impl_test.cpp @@ -102,6 +102,13 @@ private: } }; +OperationSessionInfoFromClient makeSessionInfo() { + OperationSessionInfoFromClient sessionInfo; + sessionInfo.setAutocommit(false); + sessionInfo.setStartTransaction(true); + return sessionInfo; +} + TEST_F(OpObserverTest, CollModWithCollectionOptionsAndTTLInfo) { OpObserverImpl opObserver; auto opCtx = cc().makeOperationContext(); @@ -428,7 +435,7 @@ TEST_F(OpObserverLargeTransactionTest, TransactionTooLargeWhileCommitting) { opCtx->setLogicalSessionId(sessionId); opCtx->setTxnNumber(txnNum); - OperationContextSessionMongod opSession(opCtx.get(), true, false, true); + OperationContextSessionMongod opSession(opCtx.get(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx.get()); txnParticipant->unstashTransactionResources(opCtx.get(), "insert"); @@ -609,7 +616,7 @@ TEST_F(OpObserverTransactionTest, TransactionalPrepareTest) { const TxnNumber txnNum = 2; opCtx()->setTxnNumber(txnNum); - OperationContextSessionMongod opSession(opCtx(), true, false, true); + OperationContextSessionMongod opSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); @@ -708,7 +715,7 @@ TEST_F(OpObserverTransactionTest, TransactionalPreparedCommitTest) { const TxnNumber txnNum = 2; opCtx()->setTxnNumber(txnNum); - OperationContextSessionMongod opSession(opCtx(), true, false, true); + OperationContextSessionMongod opSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); @@ -778,7 +785,7 @@ TEST_F(OpObserverTransactionTest, TransactionalPreparedAbortTest) { const TxnNumber txnNum = 2; opCtx()->setTxnNumber(txnNum); - OperationContextSessionMongod opSession(opCtx(), true, false, true); + OperationContextSessionMongod opSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); @@ -843,7 +850,7 @@ TEST_F(OpObserverTransactionTest, TransactionalUnpreparedAbortTest) { const TxnNumber txnNum = 2; opCtx()->setTxnNumber(txnNum); - OperationContextSessionMongod opSession(opCtx(), true, false, true); + OperationContextSessionMongod opSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); @@ -871,7 +878,7 @@ TEST_F(OpObserverTransactionTest, PreparingEmptyTransactionLogsEmptyApplyOps) { const TxnNumber txnNum = 2; opCtx()->setTxnNumber(txnNum); - OperationContextSessionMongod opSession(opCtx(), true, false, true); + OperationContextSessionMongod opSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "prepareTransaction"); txnParticipant->transitionToPreparedforTest(); @@ -898,7 +905,7 @@ TEST_F(OpObserverTransactionTest, PreparingTransactionWritesToTransactionTable) const TxnNumber txnNum = 2; opCtx()->setTxnNumber(txnNum); - OperationContextSessionMongod opSession(opCtx(), true, false, true); + OperationContextSessionMongod opSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "prepareTransaction"); txnParticipant->transitionToPreparedforTest(); @@ -922,7 +929,7 @@ TEST_F(OpObserverTransactionTest, AbortingUnpreparedTransactionDoesNotWriteToTra const TxnNumber txnNum = 2; opCtx()->setTxnNumber(txnNum); - OperationContextSessionMongod opSession(opCtx(), true, false, true); + OperationContextSessionMongod opSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "prepareTransaction"); @@ -939,7 +946,7 @@ TEST_F(OpObserverTransactionTest, AbortingPreparedTransactionWritesToTransaction const TxnNumber txnNum = 2; opCtx()->setTxnNumber(txnNum); - OperationContextSessionMongod opSession(opCtx(), true, false, true); + OperationContextSessionMongod opSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "prepareTransaction"); @@ -973,7 +980,7 @@ TEST_F(OpObserverTransactionTest, CommittingUnpreparedNonEmptyTransactionWritesT const TxnNumber txnNum = 2; opCtx()->setTxnNumber(txnNum); - OperationContextSessionMongod opSession(opCtx(), true, false, true); + OperationContextSessionMongod opSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "prepareTransaction"); @@ -998,7 +1005,7 @@ TEST_F(OpObserverTransactionTest, const TxnNumber txnNum = 2; opCtx()->setTxnNumber(txnNum); - OperationContextSessionMongod opSession(opCtx(), true, false, true); + OperationContextSessionMongod opSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "prepareTransaction"); @@ -1016,7 +1023,7 @@ TEST_F(OpObserverTransactionTest, CommittingPreparedTransactionWritesToTransacti const TxnNumber txnNum = 2; opCtx()->setTxnNumber(txnNum); - OperationContextSessionMongod opSession(opCtx(), true, false, true); + OperationContextSessionMongod opSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "prepareTransaction"); @@ -1050,7 +1057,7 @@ TEST_F(OpObserverTransactionTest, TransactionalInsertTest) { const TxnNumber txnNum = 2; opCtx()->setTxnNumber(txnNum); - OperationContextSessionMongod opSession(opCtx(), true, false, true); + OperationContextSessionMongod opSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); @@ -1127,7 +1134,7 @@ TEST_F(OpObserverTransactionTest, TransactionalUpdateTest) { const TxnNumber txnNum = 3; opCtx()->setTxnNumber(txnNum); - OperationContextSessionMongod opSession(opCtx(), true, false, true); + OperationContextSessionMongod opSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "update"); @@ -1193,7 +1200,7 @@ TEST_F(OpObserverTransactionTest, TransactionalDeleteTest) { const TxnNumber txnNum = 3; opCtx()->setTxnNumber(txnNum); - OperationContextSessionMongod sessionTxnState(opCtx(), true, false, true); + OperationContextSessionMongod sessionTxnState(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "delete"); diff --git a/src/mongo/db/operation_context_session_mongod.cpp b/src/mongo/db/operation_context_session_mongod.cpp index 39031f6cf1f..c2222d572a9 100644 --- a/src/mongo/db/operation_context_session_mongod.cpp +++ b/src/mongo/db/operation_context_session_mongod.cpp @@ -37,23 +37,24 @@ namespace mongo { -OperationContextSessionMongod::OperationContextSessionMongod(OperationContext* opCtx, - bool shouldCheckOutSession, - boost::optional<bool> autocommit, - boost::optional<bool> startTransaction, - boost::optional<bool> coordinator) +OperationContextSessionMongod::OperationContextSessionMongod( + OperationContext* opCtx, + bool shouldCheckOutSession, + const OperationSessionInfoFromClient& sessionInfo) : _operationContextSession(opCtx, shouldCheckOutSession) { if (shouldCheckOutSession && !opCtx->getClient()->isInDirectClient()) { const auto txnParticipant = TransactionParticipant::get(opCtx); const auto clientTxnNumber = *opCtx->getTxnNumber(); txnParticipant->refreshFromStorageIfNeeded(opCtx); - txnParticipant->beginOrContinue(clientTxnNumber, autocommit, startTransaction); + txnParticipant->beginOrContinue( + clientTxnNumber, sessionInfo.getAutocommit(), sessionInfo.getStartTransaction()); - if (startTransaction && *startTransaction) { + // If "startTransaction" is present, it must be true. + if (sessionInfo.getStartTransaction()) { // If this shard has been selected as the coordinator, set up the coordinator state // to be ready to receive votes. - if (coordinator && *coordinator) { + if (sessionInfo.getCoordinator() == boost::optional<bool>(true)) { createTransactionCoordinator(opCtx, clientTxnNumber); } } diff --git a/src/mongo/db/operation_context_session_mongod.h b/src/mongo/db/operation_context_session_mongod.h index 07425e8f57a..24180d270ce 100644 --- a/src/mongo/db/operation_context_session_mongod.h +++ b/src/mongo/db/operation_context_session_mongod.h @@ -47,9 +47,7 @@ class OperationContextSessionMongod { public: OperationContextSessionMongod(OperationContext* opCtx, bool shouldCheckOutSession, - boost::optional<bool> autocommit, - boost::optional<bool> startTransaction, - boost::optional<bool> coordinator = boost::none); + const OperationSessionInfoFromClient& sessionInfo); private: OperationContextSession _operationContextSession; diff --git a/src/mongo/db/repl/do_txn.cpp b/src/mongo/db/repl/do_txn.cpp index 0f3434d9dfa..169ae5687cc 100644 --- a/src/mongo/db/repl/do_txn.cpp +++ b/src/mongo/db/repl/do_txn.cpp @@ -263,8 +263,6 @@ Status doTxn(OperationContext* opCtx, const std::string& dbName, const BSONObj& doTxnCmd, BSONObjBuilder* result) { - auto txnNumber = opCtx->getTxnNumber(); - uassert(ErrorCodes::InvalidOptions, "doTxn can only be run with a transaction ID.", txnNumber); auto txnParticipant = TransactionParticipant::get(opCtx); uassert(ErrorCodes::InvalidOptions, "doTxn must be run within a transaction", txnParticipant); invariant(txnParticipant->inMultiDocumentTransaction()); diff --git a/src/mongo/db/repl/do_txn_test.cpp b/src/mongo/db/repl/do_txn_test.cpp index 6bcfffa897e..59c997aa4e0 100644 --- a/src/mongo/db/repl/do_txn_test.cpp +++ b/src/mongo/db/repl/do_txn_test.cpp @@ -156,7 +156,10 @@ void DoTxnTest::setUp() { // Set up the transaction and session. _opCtx->setLogicalSessionId(makeLogicalSessionIdForTest()); _opCtx->setTxnNumber(0); // TxnNumber can always be 0 because we have a new session. - _ocs.emplace(_opCtx.get(), true /* checkOutSession */, false, true); + OperationSessionInfoFromClient sessionInfo; + sessionInfo.setAutocommit(false); + sessionInfo.setStartTransaction(true); + _ocs.emplace(_opCtx.get(), true /* checkOutSession */, sessionInfo); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "doTxn"); diff --git a/src/mongo/db/s/session_catalog_migration_destination_test.cpp b/src/mongo/db/s/session_catalog_migration_destination_test.cpp index 60dc619993f..470fe242732 100644 --- a/src/mongo/db/s/session_catalog_migration_destination_test.cpp +++ b/src/mongo/db/s/session_catalog_migration_destination_test.cpp @@ -251,8 +251,7 @@ public: // requests with txnNumbers aren't allowed. To get around this, we have to manually set // up the session state and perform the insert. initializeOperationSessionInfo(innerOpCtx.get(), insertBuilder.obj(), true, true, true); - OperationContextSessionMongod sessionTxnState( - innerOpCtx.get(), true, boost::none, boost::none); + OperationContextSessionMongod sessionTxnState(innerOpCtx.get(), true, {}); const auto reply = performInserts(innerOpCtx.get(), insertRequest); ASSERT(reply.results.size() == 1); diff --git a/src/mongo/db/s/txn_two_phase_commit_cmds.cpp b/src/mongo/db/s/txn_two_phase_commit_cmds.cpp index e4b661d0b66..cb4766efc4e 100644 --- a/src/mongo/db/s/txn_two_phase_commit_cmds.cpp +++ b/src/mongo/db/s/txn_two_phase_commit_cmds.cpp @@ -419,8 +419,10 @@ public: private: void _callPrepareOnLocalParticipant(OperationContext* opCtx) { auto localParticipantPrepareTimestamp = [&]() -> Timestamp { - OperationContextSessionMongod checkOutSession( - opCtx, true, false, boost::none, false); + OperationSessionInfoFromClient sessionInfo; + sessionInfo.setAutocommit(false); + sessionInfo.setCoordinator(false); + OperationContextSessionMongod checkOutSession(opCtx, true, sessionInfo); auto txnParticipant = TransactionParticipant::get(opCtx); diff --git a/src/mongo/db/service_entry_point_common.cpp b/src/mongo/db/service_entry_point_common.cpp index 1eda9934455..7b1c0849936 100644 --- a/src/mongo/db/service_entry_point_common.cpp +++ b/src/mongo/db/service_entry_point_common.cpp @@ -105,32 +105,31 @@ using logger::LogComponent; // session for commands that can take a lock and then run another whitelisted command in // DBDirectClient. Otherwise, the nested command would try to check out a session under a lock, // which is not allowed. -const StringMap<int> sessionCommandAutomaticCheckOutWhiteList = { - {"abortTransaction", 1}, - {"aggregate", 1}, - {"applyOps", 1}, - {"commitTransaction", 1}, - {"count", 1}, - {"dbHash", 1}, - {"delete", 1}, - {"distinct", 1}, - {"doTxn", 1}, - {"explain", 1}, - {"filemd5", 1}, - {"find", 1}, - {"findandmodify", 1}, - {"findAndModify", 1}, - {"geoNear", 1}, - {"geoSearch", 1}, - {"getMore", 1}, - {"group", 1}, - {"insert", 1}, - {"killCursors", 1}, - {"prepareTransaction", 1}, - {"refreshLogicalSessionCacheNow", 1}, - {"update", 1}}; - -const StringMap<int> sessionCommandNoCheckOutWhiteList = { +const StringMap<int> sessionCheckOutList = {{"abortTransaction", 1}, + {"aggregate", 1}, + {"applyOps", 1}, + {"commitTransaction", 1}, + {"count", 1}, + {"dbHash", 1}, + {"delete", 1}, + {"distinct", 1}, + {"doTxn", 1}, + {"explain", 1}, + {"filemd5", 1}, + {"find", 1}, + {"findandmodify", 1}, + {"findAndModify", 1}, + {"geoNear", 1}, + {"geoSearch", 1}, + {"getMore", 1}, + {"group", 1}, + {"insert", 1}, + {"killCursors", 1}, + {"prepareTransaction", 1}, + {"refreshLogicalSessionCacheNow", 1}, + {"update", 1}}; + +const StringMap<int> skipSessionCheckOutList = { {"coordinateCommitTransaction", 1}, {"voteAbortTransaction", 1}, {"voteCommitTransaction", 1}}; bool shouldActivateFailCommandFailPoint(const BSONObj& data, StringData cmdName) { @@ -391,7 +390,7 @@ void appendClusterAndOperationTime(OperationContext* opCtx, void invokeInTransaction(OperationContext* opCtx, CommandInvocation* invocation, TransactionParticipant* txnParticipant, - const boost::optional<OperationSessionInfoFromClient>& sessionOptions, + const OperationSessionInfoFromClient& sessionOptions, rpc::ReplyBuilderInterface* replyBuilder) { txnParticipant->unstashTransactionResources(opCtx, invocation->definition()->getName()); ScopeGuard guard = MakeGuard([&txnParticipant, opCtx]() { @@ -404,8 +403,8 @@ void invokeInTransaction(OperationContext* opCtx, // Exceptions are used to resolve views in a sharded cluster, so they should be handled // specially to avoid unnecessary aborts. - auto startTransaction = sessionOptions->getStartTransaction(); - if (startTransaction && *startTransaction) { + // If "startTransaction" is present, it must be true. + if (sessionOptions.getStartTransaction()) { // If the first command a shard receives in a transactions fails with this code, the // shard may not be included in the final participant list if the router's retry after // resolving the view does not re-target it, which is possible if the underlying @@ -442,7 +441,7 @@ bool runCommandImpl(OperationContext* opCtx, LogicalTime startOperationTime, const ServiceEntryPointCommon::Hooks& behaviors, BSONObjBuilder* extraFieldsBuilder, - const boost::optional<OperationSessionInfoFromClient>& sessionOptions) { + const OperationSessionInfoFromClient& sessionOptions) { const Command* command = invocation->definition(); auto bytesToReserve = command->reserveBytesForReply(); // SERVER-22100: In Windows DEBUG builds, the CRT heap debugging overhead, in conjunction with the @@ -577,7 +576,7 @@ void execCommandDatabase(OperationContext* opCtx, BSONObjBuilder extraFieldsBuilder; auto startOperationTime = getClientOperationTime(opCtx); auto invocation = command->parse(opCtx, request); - boost::optional<OperationSessionInfoFromClient> sessionOptions = boost::none; + OperationSessionInfoFromClient sessionOptions; try { { @@ -611,54 +610,37 @@ void execCommandDatabase(OperationContext* opCtx, // using to service an earlier operation in the command's chain. To avoid this, only check // out sessions for commands that require them. const bool shouldCheckoutSession = static_cast<bool>(opCtx->getTxnNumber()) && - sessionCommandAutomaticCheckOutWhiteList.find(command->getName()) != - sessionCommandAutomaticCheckOutWhiteList.cend(); - - // Parse the arguments specific to multi-statement transactions. - boost::optional<bool> startMultiDocTxn = boost::none; - boost::optional<bool> autocommitVal = boost::none; - boost::optional<bool> coordinatorVal = boost::none; - if (sessionOptions) { - startMultiDocTxn = sessionOptions->getStartTransaction(); - autocommitVal = sessionOptions->getAutocommit(); - coordinatorVal = sessionOptions->getCoordinator(); - if (command->getName() == "doTxn") { - // Autocommit and 'startMultiDocTxn' are overridden for 'doTxn' to get the oplog - // entry generation behavior used for multi-document transactions. The 'doTxn' - // command still logically behaves as a commit. - autocommitVal = false; - startMultiDocTxn = true; - } - } + sessionCheckOutList.find(command->getName()) != sessionCheckOutList.cend(); // Reject commands with 'txnNumber' that do not check out the Session, since no retryable // writes or transaction machinery will be used to execute commands that do not check out // the Session. Do not check this if we are in DBDirectClient because the outer command is // responsible for checking out the Session. - if (!opCtx->getClient()->isInDirectClient()) { + const auto skipSessionCheckout = + skipSessionCheckOutList.find(command->getName()) != skipSessionCheckOutList.cend(); + const auto shouldNotCheckOutSession = !shouldCheckoutSession // + && !opCtx->getClient()->isInDirectClient() // Skip DBDirectClient. + && !skipSessionCheckout; // If we know they cannot check out, don't bother. + + if (shouldNotCheckOutSession) { uassert(ErrorCodes::OperationNotSupportedInTransaction, str::stream() << "It is illegal to run command " << command->getName() << " in a multi-document transaction.", - shouldCheckoutSession || !autocommitVal || command->getName() == "doTxn" || - sessionCommandNoCheckOutWhiteList.find(command->getName()) != - sessionCommandNoCheckOutWhiteList.cend()); + !sessionOptions.getAutocommit()); uassert(50768, str::stream() << "It is illegal to provide a txnNumber for command " << command->getName(), - shouldCheckoutSession || !opCtx->getTxnNumber() || - sessionCommandNoCheckOutWhiteList.find(command->getName()) != - sessionCommandNoCheckOutWhiteList.cend()); + !opCtx->getTxnNumber()); } - if (autocommitVal) { + if (sessionOptions.getAutocommit()) { uassertStatusOK(CommandHelpers::canUseTransactions(dbname, command->getName())); } // 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. - OperationContextSessionMongod sessionTxnState( - opCtx, shouldCheckoutSession, autocommitVal, startMultiDocTxn, coordinatorVal); + OperationContextSessionMongod sessionTxnState(opCtx, shouldCheckoutSession, sessionOptions); std::unique_ptr<MaintenanceModeSetter> mmSetter; @@ -771,8 +753,8 @@ void execCommandDatabase(OperationContext* opCtx, if (!opCtx->getClient()->isInDirectClient() || !txnParticipant || !txnParticipant->inMultiDocumentTransaction()) { const bool upconvertToSnapshot = txnParticipant && - txnParticipant->inMultiDocumentTransaction() && sessionOptions && - (sessionOptions->getStartTransaction() == boost::optional<bool>(true)); + txnParticipant->inMultiDocumentTransaction() && + sessionOptions.getStartTransaction(); readConcernArgs = uassertStatusOK( _extractReadConcern(invocation.get(), request.body, upconvertToSnapshot)); } diff --git a/src/mongo/db/transaction_participant_test.cpp b/src/mongo/db/transaction_participant_test.cpp index f2c64b5afc5..11c35d5f597 100644 --- a/src/mongo/db/transaction_participant_test.cpp +++ b/src/mongo/db/transaction_participant_test.cpp @@ -89,6 +89,15 @@ repl::OplogEntry makeOplogEntry(repl::OpTime opTime, boost::none); // post-image optime } +OperationSessionInfoFromClient makeSessionInfo(bool startTransaction = true) { + OperationSessionInfoFromClient sessionInfo; + sessionInfo.setAutocommit(false); + if (startTransaction) { + sessionInfo.setStartTransaction(startTransaction); + } + return sessionInfo; +} + class OpObserverMock : public OpObserverNoop { public: void onTransactionPrepare(OperationContext* opCtx, const OplogSlot& prepareOpTime) override; @@ -281,7 +290,7 @@ protected: TEST_F(TxnParticipantTest, TransactionThrowsLockTimeoutIfLockIsUnavailable) { const std::string dbName = "TestDB"; - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); @@ -310,7 +319,7 @@ TEST_F(TxnParticipantTest, TransactionThrowsLockTimeoutIfLockIsUnavailable) { newOpCtx.get()->setLogicalSessionId(newSessionId); newOpCtx.get()->setTxnNumber(newTxnNum); - OperationContextSessionMongod newOpCtxSession(newOpCtx.get(), true, false, true); + OperationContextSessionMongod newOpCtxSession(newOpCtx.get(), true, makeSessionInfo()); auto newTxnParticipant = TransactionParticipant::get(newOpCtx.get()); newTxnParticipant->unstashTransactionResources(newOpCtx.get(), "insert"); @@ -337,7 +346,7 @@ TEST_F(TxnParticipantTest, StashAndUnstashResources) { ASSERT(originalLocker); ASSERT(originalRecoveryUnit); - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); repl::ReadConcernArgs readConcernArgs; @@ -378,7 +387,7 @@ TEST_F(TxnParticipantTest, StashAndUnstashResources) { TEST_F(TxnParticipantTest, CannotSpecifyStartTransactionOnInProgressTxn) { // Must specify startTransaction=true and autocommit=false to start a transaction. - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); ASSERT_TRUE(txnParticipant->inMultiDocumentTransaction()); @@ -389,7 +398,7 @@ TEST_F(TxnParticipantTest, CannotSpecifyStartTransactionOnInProgressTxn) { } TEST_F(TxnParticipantTest, AutocommitRequiredOnEveryTxnOp) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); // We must have stashed transaction resources to do a second operation on the transaction. @@ -409,7 +418,7 @@ TEST_F(TxnParticipantTest, AutocommitRequiredOnEveryTxnOp) { } DEATH_TEST_F(TxnParticipantTest, AutocommitCannotBeTrue, "invariant") { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); // Passing 'autocommit=true' is not allowed and should crash. @@ -417,7 +426,7 @@ DEATH_TEST_F(TxnParticipantTest, AutocommitCannotBeTrue, "invariant") { } DEATH_TEST_F(TxnParticipantTest, StartTransactionCannotBeFalse, "invariant") { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); // Passing 'startTransaction=false' is not allowed and should crash. @@ -425,7 +434,7 @@ DEATH_TEST_F(TxnParticipantTest, StartTransactionCannotBeFalse, "invariant") { } TEST_F(TxnParticipantTest, SameTransactionPreservesStoredStatements) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); // We must have stashed transaction resources to re-open the transaction. @@ -449,7 +458,7 @@ TEST_F(TxnParticipantTest, SameTransactionPreservesStoredStatements) { } TEST_F(TxnParticipantTest, AbortClearsStoredStatements) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); auto operation = repl::OplogEntry::makeInsertOperation(kNss, kUUID, BSON("TestValue" << 0)); @@ -468,7 +477,7 @@ TEST_F(TxnParticipantTest, AbortClearsStoredStatements) { // This test makes sure the commit machinery works even when no operations are done on the // transaction. TEST_F(TxnParticipantTest, EmptyTransactionCommit) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "commitTransaction"); @@ -481,7 +490,7 @@ TEST_F(TxnParticipantTest, EmptyTransactionCommit) { } TEST_F(TxnParticipantTest, CommitTransactionSetsCommitTimestampOnPreparedTransaction) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "commitTransaction"); @@ -513,7 +522,7 @@ TEST_F(TxnParticipantTest, CommitTransactionSetsCommitTimestampOnPreparedTransac TEST_F(TxnParticipantTest, CommitTransactionWithCommitTimestampFailsOnUnpreparedTransaction) { const auto commitTimestamp = Timestamp(6, 6); - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "commitTransaction"); @@ -525,7 +534,7 @@ TEST_F(TxnParticipantTest, CommitTransactionWithCommitTimestampFailsOnUnprepared } TEST_F(TxnParticipantTest, CommitTransactionDoesNotSetCommitTimestampOnUnpreparedTransaction) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto originalFn = _opObserver->onTransactionCommitFn; _opObserver->onTransactionCommitFn = [&](boost::optional<OplogSlot> commitOplogEntryOpTime, @@ -551,7 +560,7 @@ TEST_F(TxnParticipantTest, CommitTransactionDoesNotSetCommitTimestampOnUnprepare } TEST_F(TxnParticipantTest, CommitTransactionWithoutCommitTimestampFailsOnPreparedTransaction) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "commitTransaction"); @@ -565,7 +574,7 @@ TEST_F(TxnParticipantTest, CommitTransactionWithoutCommitTimestampFailsOnPrepare } TEST_F(TxnParticipantTest, CommitTransactionWithNullCommitTimestampFailsOnPreparedTransaction) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "commitTransaction"); @@ -580,7 +589,7 @@ TEST_F(TxnParticipantTest, CommitTransactionWithNullCommitTimestampFailsOnPrepar TEST_F(TxnParticipantTest, CommitTransactionWithCommitTimestampLessThanPrepareTimestampFailsOnPreparedTransaction) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "commitTransaction"); @@ -597,7 +606,7 @@ TEST_F(TxnParticipantTest, // This test makes sure the abort machinery works even when no operations are done on the // transaction. TEST_F(TxnParticipantTest, EmptyTransactionAbort) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "abortTransaction"); @@ -609,7 +618,7 @@ TEST_F(TxnParticipantTest, EmptyTransactionAbort) { } TEST_F(TxnParticipantTest, ConcurrencyOfUnstashAndAbort) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); // The transaction may be aborted without checking out the txnParticipant. @@ -622,7 +631,7 @@ TEST_F(TxnParticipantTest, ConcurrencyOfUnstashAndAbort) { } TEST_F(TxnParticipantTest, ConcurrencyOfUnstashAndMigration) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); @@ -644,7 +653,7 @@ TEST_F(TxnParticipantTest, ConcurrencyOfUnstashAndMigration) { } TEST_F(TxnParticipantTest, ConcurrencyOfStashAndAbort) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "find"); @@ -656,7 +665,7 @@ TEST_F(TxnParticipantTest, ConcurrencyOfStashAndAbort) { } TEST_F(TxnParticipantTest, ConcurrencyOfStashAndMigration) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); @@ -675,7 +684,7 @@ TEST_F(TxnParticipantTest, ConcurrencyOfStashAndMigration) { } TEST_F(TxnParticipantTest, ConcurrencyOfAddTransactionOperationAndAbort) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); @@ -690,7 +699,7 @@ TEST_F(TxnParticipantTest, ConcurrencyOfAddTransactionOperationAndAbort) { } TEST_F(TxnParticipantTest, ConcurrencyOfAddTransactionOperationAndMigration) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "find"); @@ -710,7 +719,7 @@ TEST_F(TxnParticipantTest, ConcurrencyOfAddTransactionOperationAndMigration) { } TEST_F(TxnParticipantTest, ConcurrencyOfEndTransactionAndRetrieveOperationsAndAbort) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); @@ -724,7 +733,7 @@ TEST_F(TxnParticipantTest, ConcurrencyOfEndTransactionAndRetrieveOperationsAndAb } TEST_F(TxnParticipantTest, ConcurrencyOfEndTransactionAndRetrieveOperationsAndMigration) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); @@ -743,7 +752,7 @@ TEST_F(TxnParticipantTest, ConcurrencyOfEndTransactionAndRetrieveOperationsAndMi } TEST_F(TxnParticipantTest, ConcurrencyOfCommitUnpreparedTransactionAndAbort) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "commitTransaction"); @@ -758,7 +767,7 @@ TEST_F(TxnParticipantTest, ConcurrencyOfCommitUnpreparedTransactionAndAbort) { } TEST_F(TxnParticipantTest, ConcurrencyOfCommitPreparedTransactionAndAbort) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "commitTransaction"); @@ -775,7 +784,7 @@ TEST_F(TxnParticipantTest, ConcurrencyOfCommitPreparedTransactionAndAbort) { } TEST_F(TxnParticipantTest, ConcurrencyOfActiveUnpreparedAbortAndArbitraryAbort) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); @@ -792,7 +801,7 @@ TEST_F(TxnParticipantTest, ConcurrencyOfActiveUnpreparedAbortAndArbitraryAbort) } TEST_F(TxnParticipantTest, ConcurrencyOfActiveUnpreparedAbortAndMigration) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); @@ -815,7 +824,7 @@ TEST_F(TxnParticipantTest, ConcurrencyOfActiveUnpreparedAbortAndMigration) { } TEST_F(TxnParticipantTest, ConcurrencyOfActivePreparedAbortAndArbitraryAbort) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); @@ -833,7 +842,7 @@ TEST_F(TxnParticipantTest, ConcurrencyOfActivePreparedAbortAndArbitraryAbort) { } TEST_F(TxnParticipantTest, ConcurrencyOfPrepareTransactionAndAbort) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "prepareTransaction"); @@ -851,7 +860,7 @@ TEST_F(TxnParticipantTest, ConcurrencyOfPrepareTransactionAndAbort) { } TEST_F(TxnParticipantTest, KillSessionsDuringPrepareDoesNotAbortTransaction) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "prepareTransaction"); @@ -879,7 +888,7 @@ TEST_F(TxnParticipantTest, KillSessionsDuringPrepareDoesNotAbortTransaction) { } DEATH_TEST_F(TxnParticipantTest, AbortDuringPrepareIsFatal, "Invariant") { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "prepareTransaction"); @@ -896,7 +905,7 @@ DEATH_TEST_F(TxnParticipantTest, AbortDuringPrepareIsFatal, "Invariant") { } TEST_F(TxnParticipantTest, ThrowDuringOnTransactionPrepareAbortsTransaction) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "prepareTransaction"); @@ -911,7 +920,7 @@ TEST_F(TxnParticipantTest, ThrowDuringOnTransactionPrepareAbortsTransaction) { } TEST_F(TxnParticipantTest, KillSessionsDuringPreparedCommitDoesNotAbortTransaction) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "commitTransaction"); @@ -942,7 +951,7 @@ TEST_F(TxnParticipantTest, KillSessionsDuringPreparedCommitDoesNotAbortTransacti } TEST_F(TxnParticipantTest, ArbitraryAbortDuringPreparedCommitDoesNotAbortTransaction) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "commitTransaction"); @@ -976,7 +985,7 @@ TEST_F(TxnParticipantTest, ArbitraryAbortDuringPreparedCommitDoesNotAbortTransac DEATH_TEST_F(TxnParticipantTest, ThrowDuringPreparedOnTransactionCommitIsFatal, "Caught exception during commit") { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "commitTransaction"); @@ -987,7 +996,7 @@ DEATH_TEST_F(TxnParticipantTest, } TEST_F(TxnParticipantTest, ThrowDuringUnpreparedCommitLetsTheAbortAtEntryPointToCleanUp) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "commitTransaction"); @@ -1006,7 +1015,7 @@ TEST_F(TxnParticipantTest, ThrowDuringUnpreparedCommitLetsTheAbortAtEntryPointTo } TEST_F(TxnParticipantTest, ConcurrencyOfCommitUnpreparedTransactionAndMigration) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); @@ -1025,7 +1034,7 @@ TEST_F(TxnParticipantTest, ConcurrencyOfCommitUnpreparedTransactionAndMigration) } TEST_F(TxnParticipantTest, ConcurrencyOfPrepareTransactionAndMigration) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); @@ -1045,14 +1054,14 @@ TEST_F(TxnParticipantTest, ConcurrencyOfPrepareTransactionAndMigration) { } TEST_F(TxnParticipantTest, ContinuingATransactionWithNoResourcesAborts) { - OperationContextSessionMongod(opCtx(), true, false, true); - ASSERT_THROWS_CODE(OperationContextSessionMongod(opCtx(), true, false, boost::none), + OperationContextSessionMongod(opCtx(), true, makeSessionInfo()); + ASSERT_THROWS_CODE(OperationContextSessionMongod(opCtx(), true, makeSessionInfo(false)), AssertionException, ErrorCodes::NoSuchTransaction); } TEST_F(TxnParticipantTest, KillSessionsDoesNotAbortPreparedTransactions) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); @@ -1078,7 +1087,7 @@ TEST_F(TxnParticipantTest, KillSessionsDoesNotAbortPreparedTransactions) { } TEST_F(TxnParticipantTest, TransactionTimeoutDoesNotAbortPreparedTransactions) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); @@ -1104,7 +1113,7 @@ TEST_F(TxnParticipantTest, TransactionTimeoutDoesNotAbortPreparedTransactions) { } TEST_F(TxnParticipantTest, CannotStartNewTransactionWhilePreparedTransactionInProgress) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); @@ -1150,7 +1159,7 @@ TEST_F(TxnParticipantTest, CannotStartNewTransactionWhilePreparedTransactionInPr } TEST_F(TxnParticipantTest, CannotInsertInPreparedTransaction) { - OperationContextSessionMongod outerScopedSession(opCtx(), true, false, true); + OperationContextSessionMongod outerScopedSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); @@ -1168,7 +1177,7 @@ TEST_F(TxnParticipantTest, CannotInsertInPreparedTransaction) { } TEST_F(TxnParticipantTest, MigrationThrowsOnPreparedTransaction) { - OperationContextSessionMongod outerScopedSession(opCtx(), true, false, true); + OperationContextSessionMongod outerScopedSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); @@ -1188,7 +1197,7 @@ TEST_F(TxnParticipantTest, MigrationThrowsOnPreparedTransaction) { } TEST_F(TxnParticipantTest, ImplictAbortDoesNotAbortPreparedTransaction) { - OperationContextSessionMongod outerScopedSession(opCtx(), true, false, true); + OperationContextSessionMongod outerScopedSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); @@ -1205,7 +1214,7 @@ TEST_F(TxnParticipantTest, ImplictAbortDoesNotAbortPreparedTransaction) { } DEATH_TEST_F(TxnParticipantTest, AbortIsIllegalDuringCommittingPreparedTransaction, "invariant") { - OperationContextSessionMongod outerScopedSession(opCtx(), true, false, true); + OperationContextSessionMongod outerScopedSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); @@ -1237,14 +1246,14 @@ DEATH_TEST_F(TxnParticipantTest, AbortIsIllegalDuringCommittingPreparedTransacti } TEST_F(TxnParticipantTest, CannotContinueNonExistentTransaction) { - ASSERT_THROWS_CODE(OperationContextSessionMongod(opCtx(), true, false, boost::none), + ASSERT_THROWS_CODE(OperationContextSessionMongod(opCtx(), true, makeSessionInfo(false)), AssertionException, ErrorCodes::NoSuchTransaction); } // Tests that a transaction aborts if it becomes too large before trying to commit it. TEST_F(TxnParticipantTest, TransactionTooLargeWhileBuilding) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); @@ -1264,7 +1273,7 @@ TEST_F(TxnParticipantTest, TransactionTooLargeWhileBuilding) { } TEST_F(TxnParticipantTest, StashInNestedSessionIsANoop) { - OperationContextSessionMongod outerScopedSession(opCtx(), true, false, true); + OperationContextSessionMongod outerScopedSession(opCtx(), true, makeSessionInfo()); Locker* originalLocker = opCtx()->lockState(); RecoveryUnit* originalRecoveryUnit = opCtx()->recoveryUnit(); ASSERT(originalLocker); @@ -1289,7 +1298,7 @@ TEST_F(TxnParticipantTest, StashInNestedSessionIsANoop) { { // Make it look like we're in a DBDirectClient running a nested operation. DirectClientSetter inDirectClient(opCtx()); - OperationContextSessionMongod innerScopedSession(opCtx(), true, boost::none, boost::none); + OperationContextSessionMongod innerScopedSession(opCtx(), true, {}); txnParticipant->stashTransactionResources(opCtx()); @@ -1303,7 +1312,7 @@ TEST_F(TxnParticipantTest, StashInNestedSessionIsANoop) { TEST_F(TxnParticipantTest, UnstashInNestedSessionIsANoop) { - OperationContextSessionMongod outerScopedSession(opCtx(), true, false, true); + OperationContextSessionMongod outerScopedSession(opCtx(), true, makeSessionInfo()); Locker* originalLocker = opCtx()->lockState(); RecoveryUnit* originalRecoveryUnit = opCtx()->recoveryUnit(); @@ -1322,7 +1331,7 @@ TEST_F(TxnParticipantTest, UnstashInNestedSessionIsANoop) { { // Make it look like we're in a DBDirectClient running a nested operation. DirectClientSetter inDirectClient(opCtx()); - OperationContextSessionMongod innerScopedSession(opCtx(), true, boost::none, boost::none); + OperationContextSessionMongod innerScopedSession(opCtx(), true, {}); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "find"); @@ -1347,7 +1356,7 @@ protected: auto autocommit = false; auto startTransaction = true; OperationContextSessionMongod opCtxSession( - opCtx(), true /* shouldCheckOutSession */, autocommit, startTransaction); + opCtx(), true /* shouldCheckOutSession */, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); ASSERT(txnParticipant->inMultiDocumentTransaction()); @@ -1360,7 +1369,7 @@ protected: auto autocommit = false; auto startTransaction = true; OperationContextSessionMongod opCtxSession( - opCtx(), true /* shouldCheckOutSession */, autocommit, startTransaction); + opCtx(), true /* shouldCheckOutSession */, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); ASSERT(txnParticipant->inMultiDocumentTransaction()); @@ -1376,7 +1385,7 @@ protected: auto autocommit = false; auto startTransaction = true; OperationContextSessionMongod opCtxSession( - opCtx(), true /* shouldCheckOutSession */, autocommit, startTransaction); + opCtx(), true /* shouldCheckOutSession */, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); ASSERT(txnParticipant->inMultiDocumentTransaction()); @@ -1394,7 +1403,7 @@ protected: auto autocommit = false; auto startTransaction = true; OperationContextSessionMongod opCtxSession( - opCtx(), true /* shouldCheckOutSession */, autocommit, startTransaction); + opCtx(), true /* shouldCheckOutSession */, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); ASSERT(txnParticipant->inMultiDocumentTransaction()); @@ -1411,16 +1420,13 @@ protected: } void cannotSpecifyStartTransactionOnStartedRetryableWrite() { - boost::optional<bool> autocommit = boost::none; - boost::optional<bool> startTransaction = boost::none; - OperationContextSessionMongod opCtxSession( - opCtx(), true /* shouldCheckOutSession */, autocommit, startTransaction); + OperationContextSessionMongod opCtxSession(opCtx(), true /* shouldCheckOutSession */, {}); auto txnParticipant = TransactionParticipant::get(opCtx()); ASSERT_FALSE(txnParticipant->inMultiDocumentTransaction()); - autocommit = false; - startTransaction = true; + auto autocommit = false; + auto startTransaction = true; ASSERT_THROWS_CODE( txnParticipant->beginOrContinue(*opCtx()->getTxnNumber(), autocommit, startTransaction), AssertionException, @@ -1505,7 +1511,7 @@ TEST_F(ConfigTxnParticipantTest, CannotSpecifyStartTransactionOnStartedRetryable } TEST_F(TxnParticipantTest, KillSessionsDuringUnpreparedAbortSucceeds) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "abortTransaction"); @@ -1525,7 +1531,7 @@ TEST_F(TxnParticipantTest, KillSessionsDuringUnpreparedAbortSucceeds) { } TEST_F(TxnParticipantTest, ActiveAbortIsLegalDuringUnpreparedAbort) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "abortTransaction"); @@ -1553,7 +1559,7 @@ TEST_F(TxnParticipantTest, ActiveAbortIsLegalDuringUnpreparedAbort) { } TEST_F(TxnParticipantTest, ThrowDuringUnpreparedOnTransactionAbort) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "abortTransaction"); @@ -1565,7 +1571,7 @@ TEST_F(TxnParticipantTest, ThrowDuringUnpreparedOnTransactionAbort) { } TEST_F(TxnParticipantTest, KillSessionsDuringPreparedAbortFails) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "abortTransaction"); txnParticipant->prepareTransaction(opCtx(), {}); @@ -1587,7 +1593,7 @@ TEST_F(TxnParticipantTest, KillSessionsDuringPreparedAbortFails) { } TEST_F(TxnParticipantTest, ActiveAbortSucceedsDuringPreparedAbort) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "abortTransaction"); txnParticipant->prepareTransaction(opCtx(), {}); @@ -1616,7 +1622,7 @@ TEST_F(TxnParticipantTest, ActiveAbortSucceedsDuringPreparedAbort) { } TEST_F(TxnParticipantTest, ThrowDuringPreparedOnTransactionAbortIsFatal) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "abortTransaction"); txnParticipant->prepareTransaction(opCtx(), {}); @@ -1661,7 +1667,7 @@ TEST_F(TransactionsMetricsTest, IncrementTotalStartedUponStartTransaction) { unsigned long long beforeTransactionStart = ServerTransactionsMetrics::get(opCtx())->getTotalStarted(); - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); // Tests that the total transactions started counter is incremented by 1 when a new transaction // is started. @@ -1670,7 +1676,7 @@ TEST_F(TransactionsMetricsTest, IncrementTotalStartedUponStartTransaction) { } TEST_F(TransactionsMetricsTest, IncrementTotalCommittedOnCommit) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "commitTransaction"); @@ -1684,7 +1690,7 @@ TEST_F(TransactionsMetricsTest, IncrementTotalCommittedOnCommit) { } TEST_F(TransactionsMetricsTest, IncrementTotalAbortedUponAbort) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); @@ -1702,7 +1708,7 @@ TEST_F(TransactionsMetricsTest, TrackTotalOpenTransactionsWithAbort) { ServerTransactionsMetrics::get(opCtx())->getCurrentOpen(); // Tests that starting a transaction increments the open transactions counter by 1. - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getCurrentOpen(), @@ -1724,7 +1730,7 @@ TEST_F(TransactionsMetricsTest, TrackTotalOpenTransactionsWithCommit) { ServerTransactionsMetrics::get(opCtx())->getCurrentOpen(); // Tests that starting a transaction increments the open transactions counter by 1. - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getCurrentOpen(), @@ -1750,7 +1756,7 @@ TEST_F(TransactionsMetricsTest, TrackTotalActiveAndInactiveTransactionsWithCommi ServerTransactionsMetrics::get(opCtx())->getCurrentInactive(); // Starting the transaction should put it into an inactive state. - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getCurrentInactive(), beforeInactiveCounter + 1); @@ -1790,7 +1796,7 @@ TEST_F(TransactionsMetricsTest, TrackTotalActiveAndInactiveTransactionsWithStash ServerTransactionsMetrics::get(opCtx())->getCurrentInactive(); // Starting the transaction should put it into an inactive state. - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getCurrentInactive(), beforeInactiveCounter + 1); @@ -1823,7 +1829,7 @@ TEST_F(TransactionsMetricsTest, TrackTotalActiveAndInactiveTransactionsWithUnsta ServerTransactionsMetrics::get(opCtx())->getCurrentInactive(); // Starting the transaction should put it into an inactive state. - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); ASSERT_EQ(ServerTransactionsMetrics::get(opCtx())->getCurrentInactive(), beforeInactiveCounter + 1); @@ -1844,7 +1850,7 @@ TEST_F(TransactionsMetricsTest, TrackTotalActiveAndInactiveTransactionsWithUnsta TEST_F(TransactionsMetricsTest, SingleTransactionStatsDurationShouldBeSetUponCommit) { auto tickSource = initMockTickSource(); - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "commitTransaction"); // The transaction machinery cannot store an empty locker. @@ -1862,7 +1868,7 @@ TEST_F(TransactionsMetricsTest, SingleTransactionStatsDurationShouldBeSetUponCom TEST_F(TransactionsMetricsTest, SingleTransactionStatsDurationShouldBeSetUponAbort) { auto tickSource = initMockTickSource(); - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); @@ -1878,7 +1884,7 @@ TEST_F(TransactionsMetricsTest, SingleTransactionStatsDurationShouldBeSetUponAbo TEST_F(TransactionsMetricsTest, SingleTransactionStatsDurationShouldKeepIncreasingUntilCommit) { auto tickSource = initMockTickSource(); - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "commitTransaction"); // The transaction machinery cannot store an empty locker. @@ -1909,7 +1915,7 @@ TEST_F(TransactionsMetricsTest, SingleTransactionStatsDurationShouldKeepIncreasi TEST_F(TransactionsMetricsTest, SingleTransactionStatsDurationShouldKeepIncreasingUntilAbort) { auto tickSource = initMockTickSource(); - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); // The transaction machinery cannot store an empty locker. @@ -1940,7 +1946,7 @@ TEST_F(TransactionsMetricsTest, SingleTransactionStatsDurationShouldKeepIncreasi TEST_F(TransactionsMetricsTest, TimeActiveMicrosShouldBeSetUponUnstashAndStash) { auto tickSource = initMockTickSource(); - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); // Time active should be zero. @@ -1987,7 +1993,7 @@ TEST_F(TransactionsMetricsTest, TimeActiveMicrosShouldBeSetUponUnstashAndStash) TEST_F(TransactionsMetricsTest, TimeActiveMicrosShouldBeSetUponUnstashAndAbort) { auto tickSource = initMockTickSource(); - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); // Time active should be zero. @@ -2015,7 +2021,7 @@ TEST_F(TransactionsMetricsTest, TimeActiveMicrosShouldBeSetUponUnstashAndAbort) TEST_F(TransactionsMetricsTest, TimeActiveMicrosShouldNotBeSetUponAbortOnly) { auto tickSource = initMockTickSource(); - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); // Time active should be zero. @@ -2037,7 +2043,7 @@ TEST_F(TransactionsMetricsTest, TimeActiveMicrosShouldNotBeSetUponAbortOnly) { TEST_F(TransactionsMetricsTest, TimeActiveMicrosShouldIncreaseUntilStash) { auto tickSource = initMockTickSource(); - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); // Time active should be zero. @@ -2074,7 +2080,7 @@ TEST_F(TransactionsMetricsTest, TimeActiveMicrosShouldIncreaseUntilStash) { TEST_F(TransactionsMetricsTest, TimeActiveMicrosShouldIncreaseUntilCommit) { auto tickSource = initMockTickSource(); - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); // Time active should be zero. @@ -2110,7 +2116,7 @@ TEST_F(TransactionsMetricsTest, TimeActiveMicrosShouldIncreaseUntilCommit) { TEST_F(TransactionsMetricsTest, TimeActiveMicrosShouldNotBeSetIfUnstashHasBadReadConcernArgs) { auto tickSource = initMockTickSource(); - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); // Initialize bad read concern args (!readConcernArgs.isEmpty()). @@ -2146,7 +2152,7 @@ TEST_F(TransactionsMetricsTest, TimeActiveMicrosShouldNotBeSetIfUnstashHasBadRea } TEST_F(TransactionsMetricsTest, AdditiveMetricsObjectsShouldBeAddedTogetherUponStash) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); // Initialize field values for both AdditiveMetrics objects. @@ -2182,7 +2188,7 @@ TEST_F(TransactionsMetricsTest, AdditiveMetricsObjectsShouldBeAddedTogetherUponS } TEST_F(TransactionsMetricsTest, AdditiveMetricsObjectsShouldBeAddedTogetherUponCommit) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); // Initialize field values for both AdditiveMetrics objects. @@ -2218,7 +2224,7 @@ TEST_F(TransactionsMetricsTest, AdditiveMetricsObjectsShouldBeAddedTogetherUponC } TEST_F(TransactionsMetricsTest, AdditiveMetricsObjectsShouldBeAddedTogetherUponAbort) { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); // Initialize field values for both AdditiveMetrics objects. @@ -2255,7 +2261,7 @@ TEST_F(TransactionsMetricsTest, AdditiveMetricsObjectsShouldBeAddedTogetherUponA TEST_F(TransactionsMetricsTest, TimeInactiveMicrosShouldBeSetUponUnstashAndStash) { auto tickSource = initMockTickSource(); - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); // Time inactive should have increased. @@ -2294,7 +2300,7 @@ TEST_F(TransactionsMetricsTest, TimeInactiveMicrosShouldBeSetUponUnstashAndStash TEST_F(TransactionsMetricsTest, TimeInactiveMicrosShouldBeSetUponUnstashAndAbort) { auto tickSource = initMockTickSource(); - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); // Time inactive should be greater than or equal to zero. @@ -2327,7 +2333,7 @@ TEST_F(TransactionsMetricsTest, TimeInactiveMicrosShouldBeSetUponUnstashAndAbort TEST_F(TransactionsMetricsTest, TimeInactiveMicrosShouldIncreaseUntilCommit) { auto tickSource = initMockTickSource(); - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); // Time inactive should be greater than or equal to zero. @@ -2366,7 +2372,7 @@ TEST_F(TransactionsMetricsTest, ReportStashedResources) { ASSERT(opCtx()->lockState()); ASSERT(opCtx()->recoveryUnit()); - OperationContextSessionMongod opCtxSession(opCtx(), true, autocommit, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); // Create a ClientMetadata object and set it on ClientMetadataIsMasterState. BSONObjBuilder builder; @@ -2462,7 +2468,7 @@ TEST_F(TransactionsMetricsTest, ReportUnstashedResources) { ASSERT(opCtx()->recoveryUnit()); const auto autocommit = false; - OperationContextSessionMongod opCtxSession(opCtx(), true, autocommit, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); repl::ReadConcernArgs readConcernArgs; ASSERT_OK(readConcernArgs.initialize(BSON("find" @@ -2520,7 +2526,7 @@ TEST_F(TransactionsMetricsTest, ReportUnstashedResourcesForARetryableWrite) { ASSERT(opCtx()->lockState()); ASSERT(opCtx()->recoveryUnit()); - OperationContextSessionMongod opCtxSession(opCtx(), true, boost::none, boost::none); + OperationContextSessionMongod opCtxSession(opCtx(), true, {}); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "find"); @@ -2567,7 +2573,7 @@ TEST_F(TransactionsMetricsTest, LastClientInfoShouldUpdateUponStash) { clientMetadataIsMasterState.setClientMetadata(opCtx()->getClient(), std::move(clientMetadata.getValue())); - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); // The transaction machinery cannot store an empty locker. @@ -2604,7 +2610,7 @@ TEST_F(TransactionsMetricsTest, LastClientInfoShouldUpdateUponCommit) { clientMetadataIsMasterState.setClientMetadata(opCtx()->getClient(), std::move(clientMetadata.getValue())); - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); // The transaction machinery cannot store an empty locker. @@ -2628,7 +2634,7 @@ TEST_F(TransactionsMetricsTest, LastClientInfoShouldUpdateUponAbort) { clientMetadataIsMasterState.setClientMetadata(opCtx()->getClient(), std::move(clientMetadata.getValue())); - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); txnParticipant->unstashTransactionResources(opCtx(), "insert"); txnParticipant->abortActiveTransaction(opCtx()); @@ -2767,7 +2773,7 @@ TEST_F(TransactionsMetricsTest, TestTransactionInfoForLogAfterCommit) { const int metricValue = 1; setupAdditiveMetrics(metricValue, opCtx()); - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); repl::ReadConcernArgs readConcernArgs; ASSERT_OK(readConcernArgs.initialize(BSON("find" @@ -2804,7 +2810,7 @@ TEST_F(TransactionsMetricsTest, TestTransactionInfoForLogAfterAbort) { const int metricValue = 1; setupAdditiveMetrics(metricValue, opCtx()); - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); repl::ReadConcernArgs readConcernArgs; ASSERT_OK(readConcernArgs.initialize(BSON("find" @@ -2837,7 +2843,7 @@ TEST_F(TransactionsMetricsTest, TestTransactionInfoForLogAfterAbort) { } DEATH_TEST_F(TransactionsMetricsTest, TestTransactionInfoForLogWithNoLockerInfoStats, "invariant") { - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); repl::ReadConcernArgs readConcernArgs; ASSERT_OK(readConcernArgs.initialize(BSON("find" @@ -2861,7 +2867,7 @@ DEATH_TEST_F(TransactionsMetricsTest, TestTransactionInfoForLogWithNoLockerInfoS TEST_F(TransactionsMetricsTest, LogTransactionInfoAfterSlowCommit) { auto tickSource = initMockTickSource(); - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); repl::ReadConcernArgs readConcernArgs; ASSERT_OK(readConcernArgs.initialize(BSON("find" @@ -2896,7 +2902,7 @@ TEST_F(TransactionsMetricsTest, LogTransactionInfoAfterSlowCommit) { TEST_F(TransactionsMetricsTest, LogTransactionInfoAfterSlowAbort) { auto tickSource = initMockTickSource(); - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); repl::ReadConcernArgs readConcernArgs; ASSERT_OK(readConcernArgs.initialize(BSON("find" @@ -2931,7 +2937,7 @@ TEST_F(TransactionsMetricsTest, LogTransactionInfoAfterSlowAbort) { TEST_F(TransactionsMetricsTest, LogTransactionInfoAfterSlowStashedAbort) { auto tickSource = initMockTickSource(); - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); repl::ReadConcernArgs readConcernArgs; ASSERT_OK(readConcernArgs.initialize(BSON("find" @@ -2970,7 +2976,7 @@ TEST_F(TransactionsMetricsTest, LogTransactionInfoAfterSlowStashedAbort) { TEST_F(TxnParticipantTest, WhenOldestTSRemovedNextOldestBecomesNewOldest) { auto totalActiveTxnTS = ServerTransactionsMetrics::get(opCtx())->getTotalActiveTS(); - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); // Check that there are no Timestamps in the set. @@ -3008,7 +3014,7 @@ TEST_F(TxnParticipantTest, WhenOldestTSRemovedNextOldestBecomesNewOldest) { newOpCtx.get()->setLogicalSessionId(newSessionId); newOpCtx.get()->setTxnNumber(newTxnNum); - OperationContextSessionMongod newOpCtxSession(newOpCtx.get(), true, false, true); + OperationContextSessionMongod newOpCtxSession(newOpCtx.get(), true, makeSessionInfo()); auto newTxnParticipant = TransactionParticipant::get(newOpCtx.get()); newTxnParticipant->unstashTransactionResources(newOpCtx.get(), "prepareTransaction"); @@ -3041,7 +3047,7 @@ TEST_F(TxnParticipantTest, WhenOldestTSRemovedNextOldestBecomesNewOldest) { TEST_F(TxnParticipantTest, ReturnNullTimestampIfNoOldestActiveTimestamp) { auto totalActiveTxnTS = ServerTransactionsMetrics::get(opCtx())->getTotalActiveTS(); - OperationContextSessionMongod opCtxSession(opCtx(), true, false, true); + OperationContextSessionMongod opCtxSession(opCtx(), true, makeSessionInfo()); auto txnParticipant = TransactionParticipant::get(opCtx()); // Check that there are no Timestamps in the set. @@ -3075,7 +3081,7 @@ TEST_F(TxnParticipantTest, ReturnNullTimestampIfNoOldestActiveTimestamp) { newOpCtx.get()->setLogicalSessionId(newSessionId); newOpCtx.get()->setTxnNumber(newTxnNum); - OperationContextSessionMongod newOpCtxSession(newOpCtx.get(), true, false, true); + OperationContextSessionMongod newOpCtxSession(newOpCtx.get(), true, makeSessionInfo()); auto newTxnParticipant = TransactionParticipant::get(newOpCtx.get()); newTxnParticipant->unstashTransactionResources(newOpCtx.get(), "prepareTransaction"); diff --git a/src/mongo/dbtests/storage_timestamp_tests.cpp b/src/mongo/dbtests/storage_timestamp_tests.cpp index 753898d6a2a..9043da447ee 100644 --- a/src/mongo/dbtests/storage_timestamp_tests.cpp +++ b/src/mongo/dbtests/storage_timestamp_tests.cpp @@ -2499,7 +2499,10 @@ public: _opCtx->setLogicalSessionId(sessionId); _opCtx->setTxnNumber(26); - ocs = std::make_unique<OperationContextSessionMongod>(_opCtx, true, false, true); + OperationSessionInfoFromClient sessionInfo; + sessionInfo.setAutocommit(false); + sessionInfo.setStartTransaction(true); + ocs = std::make_unique<OperationContextSessionMongod>(_opCtx, true, sessionInfo); auto txnParticipant = TransactionParticipant::get(_opCtx); ASSERT(txnParticipant); diff --git a/src/mongo/s/commands/strategy.cpp b/src/mongo/s/commands/strategy.cpp index a73773adb40..0426f19d2bd 100644 --- a/src/mongo/s/commands/strategy.cpp +++ b/src/mongo/s/commands/strategy.cpp @@ -388,7 +388,7 @@ void runCommand(OperationContext* opCtx, initializeOperationSessionInfo(opCtx, request.body, command->requiresAuth(), true, true); try { - if (osi && osi->getAutocommit()) { + if (osi.getAutocommit()) { scopedSession.emplace(opCtx); auto txnRouter = TransactionRouter::get(opCtx); @@ -397,7 +397,7 @@ void runCommand(OperationContext* opCtx, auto txnNumber = opCtx->getTxnNumber(); invariant(txnNumber); - auto startTxnSetting = osi->getStartTransaction(); + auto startTxnSetting = osi.getStartTransaction(); bool startTransaction = startTxnSetting ? *startTxnSetting : false; uassertStatusOK(CommandHelpers::canUseTransactions(nss.db(), command->getName())); |