diff options
3 files changed, 24 insertions, 53 deletions
diff --git a/jstests/core/txns/no_writes_to_system_collections_in_txn.js b/jstests/core/txns/no_writes_to_system_collections_in_txn.js index fa2c9c334e0..587d167efeb 100644 --- a/jstests/core/txns/no_writes_to_system_collections_in_txn.js +++ b/jstests/core/txns/no_writes_to_system_collections_in_txn.js @@ -24,20 +24,20 @@ assert.throws(() => session.abortTransaction()); session.startTransaction({readConcern: {level: "snapshot"}}); - assert.commandFailedWithCode(systemColl.insert({name: "new"}), 50784); + assert.commandFailedWithCode(systemColl.insert({name: "new"}), 50791); assert.throws(() => session.abortTransaction()); session.startTransaction({readConcern: {level: "snapshot"}}); - assert.commandFailedWithCode(systemColl.update({name: 0}, {$set: {name: "jungsoo"}}), 50783); + assert.commandFailedWithCode(systemColl.update({name: 0}, {$set: {name: "jungsoo"}}), 50791); assert.throws(() => session.abortTransaction()); session.startTransaction({readConcern: {level: "snapshot"}}); assert.commandFailedWithCode( - systemColl.update({name: "nonexistent"}, {$set: {name: "jungsoo"}}, {upsert: true}), 50783); + systemColl.update({name: "nonexistent"}, {$set: {name: "jungsoo"}}, {upsert: true}), 50791); assert.throws(() => session.abortTransaction()); session.startTransaction({readConcern: {level: "snapshot"}}); - assert.commandFailedWithCode(systemColl.remove({name: 0}), 50782); + assert.commandFailedWithCode(systemColl.remove({name: 0}), 50791); assert.throws(() => session.abortTransaction()); assert.commandWorked(systemColl.remove({_id: {$exists: true}})); diff --git a/jstests/core/txns/no_writes_to_unreplicated_collections_in_txn.js b/jstests/core/txns/no_writes_to_unreplicated_collections_in_txn.js index 3e55c9b85c5..51527f2e780 100644 --- a/jstests/core/txns/no_writes_to_unreplicated_collections_in_txn.js +++ b/jstests/core/txns/no_writes_to_unreplicated_collections_in_txn.js @@ -26,21 +26,21 @@ assert.throws(() => session.abortTransaction()); session.startTransaction({readConcern: {level: "snapshot"}}); - assert.commandFailedWithCode(unreplicatedColl.insert({_id: "new"}), 50780); + assert.commandFailedWithCode(unreplicatedColl.insert({_id: "new"}), 50790); assert.throws(() => session.abortTransaction()); session.startTransaction({readConcern: {level: "snapshot"}}); assert.commandFailedWithCode(unreplicatedColl.update({_id: 0}, {$set: {name: "jungsoo"}}), - 50779); + 50790); assert.throws(() => session.abortTransaction()); session.startTransaction({readConcern: {level: "snapshot"}}); assert.commandFailedWithCode( unreplicatedColl.update({_id: "nonexistent"}, {$set: {name: "jungsoo"}}, {upsert: true}), - 50779); + 50790); assert.throws(() => session.abortTransaction()); session.startTransaction({readConcern: {level: "snapshot"}}); - assert.commandFailedWithCode(unreplicatedColl.remove({_id: 0}), 50778); + assert.commandFailedWithCode(unreplicatedColl.remove({_id: 0}), 50790); assert.throws(() => session.abortTransaction()); }()); diff --git a/src/mongo/db/commands/write_commands/write_commands.cpp b/src/mongo/db/commands/write_commands/write_commands.cpp index c29a1baac94..7f0b94586fe 100644 --- a/src/mongo/db/commands/write_commands/write_commands.cpp +++ b/src/mongo/db/commands/write_commands/write_commands.cpp @@ -232,6 +232,7 @@ private: void run(OperationContext* opCtx, CommandReplyBuilder* result) final { try { try { + _transactionChecks(opCtx); BSONObjBuilder bob = result->getBodyBuilder(); command()->runImpl(opCtx, *_request, bob); CommandHelpers::extractOrAppendOk(bob); @@ -282,6 +283,21 @@ private: return static_cast<const WriteCommand*>(definition()); } + void _transactionChecks(OperationContext* opCtx) const { + auto session = OperationContextSession::get(opCtx); + if (!session || !session->inSnapshotReadOrMultiDocumentTransaction()) + return; + uassert(50791, + str::stream() << "Cannot write to system collection " << ns().toString() + << " within a transaction.", + !ns().isSystem()); + auto replCoord = repl::ReplicationCoordinator::get(opCtx); + uassert(50790, + str::stream() << "Cannot write to unreplicated collection " << ns().toString() + << " within a transaction.", + !replCoord->isOplogDisabledFor(opCtx, ns())); + } + const OpMsgRequest* _request; NamespaceString _ns; }; @@ -307,22 +323,7 @@ public: void runImpl(OperationContext* opCtx, const OpMsgRequest& request, BSONObjBuilder& result) const final { - const auto session = OperationContextSession::get(opCtx); - const auto inTransaction = session && session->inSnapshotReadOrMultiDocumentTransaction(); - const auto batch = InsertOp::parse(request); - uassert(50784, - str::stream() << "Cannot write to system collection " << batch.getNamespace().ns() - << " within a transaction.", - !(inTransaction && batch.getNamespace().isSystem())); - - const auto replCoord = repl::ReplicationCoordinator::get(opCtx); - uassert(50780, - str::stream() << "Cannot write to unreplicated collection " - << batch.getNamespace().ns() - << " within a transaction.", - !(inTransaction && replCoord->isOplogDisabledFor(opCtx, batch.getNamespace()))); - auto reply = performInserts(opCtx, batch); serializeReply(opCtx, ReplyStyle::kNotUpdate, @@ -352,22 +353,7 @@ public: void runImpl(OperationContext* opCtx, const OpMsgRequest& request, BSONObjBuilder& result) const final { - const auto session = OperationContextSession::get(opCtx); - const auto inTransaction = session && session->inSnapshotReadOrMultiDocumentTransaction(); - const auto batch = UpdateOp::parse(request); - uassert(50783, - str::stream() << "Cannot write to system collection " << batch.getNamespace().ns() - << " within a transaction.", - !(inTransaction && batch.getNamespace().isSystem())); - - const auto replCoord = repl::ReplicationCoordinator::get(opCtx); - uassert(50779, - str::stream() << "Cannot write to unreplicated collection " - << batch.getNamespace().ns() - << " within a transaction.", - !(inTransaction && replCoord->isOplogDisabledFor(opCtx, batch.getNamespace()))); - auto reply = performUpdates(opCtx, batch); serializeReply(opCtx, ReplyStyle::kUpdate, @@ -431,22 +417,7 @@ public: void runImpl(OperationContext* opCtx, const OpMsgRequest& request, BSONObjBuilder& result) const final { - const auto session = OperationContextSession::get(opCtx); - const auto inTransaction = session && session->inSnapshotReadOrMultiDocumentTransaction(); - const auto batch = DeleteOp::parse(request); - uassert(50782, - str::stream() << "Cannot write to system collection " << batch.getNamespace().ns() - << " within a transaction.", - !(inTransaction && batch.getNamespace().isSystem())); - - const auto replCoord = repl::ReplicationCoordinator::get(opCtx); - uassert(50778, - str::stream() << "Cannot write to unreplicated collection " - << batch.getNamespace().ns() - << " within a transaction.", - !(inTransaction && replCoord->isOplogDisabledFor(opCtx, batch.getNamespace()))); - auto reply = performDeletes(opCtx, batch); serializeReply(opCtx, ReplyStyle::kNotUpdate, |