mirror of
https://github.com/mongodb/mongo.git
synced 2024-11-30 00:56:44 +01:00
68 lines
2.9 KiB
JavaScript
68 lines
2.9 KiB
JavaScript
/**
|
|
* Tests the write conflict behavior while the "skipWriteConflictRetries" failpoint is enabled
|
|
* between operations performed outside of a multi-statement transaction when another operation is
|
|
* being performed concurrently inside of a multi-statement transaction.
|
|
*
|
|
* Note that jstests/core/txns/write_conflicts_with_non_txns.js tests the write conflict behavior
|
|
* while the "skipWriteConflictRetries" failpoint isn't enabled.
|
|
*
|
|
* @tags: [uses_transactions, uses_prepare_transaction]
|
|
*/
|
|
(function() {
|
|
"use strict";
|
|
|
|
load("jstests/core/txns/libs/prepare_helpers.js");
|
|
|
|
const rst = new ReplSetTest({nodes: 1});
|
|
rst.startSet();
|
|
rst.initiate();
|
|
|
|
const primary = rst.getPrimary();
|
|
const testDB = primary.getDB("test");
|
|
const testColl = testDB.getCollection("skip_write_conflict_retries_failpoint");
|
|
|
|
const session = primary.startSession({causalConsistency: false});
|
|
const sessionDB = session.getDatabase(testDB.getName());
|
|
const sessionColl = sessionDB.getCollection(testColl.getName());
|
|
|
|
assert.commandWorked(testColl.runCommand(
|
|
"createIndexes",
|
|
{indexes: [{key: {a: 1}, name: "a_1", unique: true}], writeConcern: {w: "majority"}}));
|
|
|
|
assert.commandWorked(
|
|
testDB.adminCommand({configureFailPoint: "skipWriteConflictRetries", mode: "alwaysOn"}));
|
|
|
|
// A non-transactional insert would ordinarily keep retrying if it conflicts with a write
|
|
// operation performed inside a multi-statement transaction. However, with the
|
|
// "skipWriteConflictRetries" failpoint enabled, the non-transactional insert should immediately
|
|
// fail with a WriteConflict error response.
|
|
session.startTransaction();
|
|
assert.commandWorked(sessionColl.insert({_id: "from transaction", a: 0}));
|
|
|
|
assert.commandFailedWithCode(testColl.insert({_id: "from outside transaction", a: 0}),
|
|
ErrorCodes.WriteConflict);
|
|
|
|
assert.commandWorked(session.commitTransaction_forTesting());
|
|
assert.eq(testColl.findOne({a: 0}), {_id: "from transaction", a: 0});
|
|
|
|
// A non-transactional update would ordinarily keep retrying if it conflicts with a write
|
|
// operation performed inside a multi-statement transaction. However, with the
|
|
// "skipWriteConflictRetries" failpoint enabled, the non-transactional insert should immediately
|
|
// fail with a WriteConflict error response.
|
|
session.startTransaction();
|
|
assert.commandWorked(sessionColl.insert({_id: "from prepared transaction", a: 1}));
|
|
const prepareTimestamp = PrepareHelpers.prepareTransaction(session);
|
|
|
|
assert.commandFailedWithCode(testColl.update({_id: "from transaction"}, {$set: {a: 1}}),
|
|
ErrorCodes.WriteConflict);
|
|
|
|
assert.commandWorked(PrepareHelpers.commitTransaction(session, prepareTimestamp));
|
|
assert.eq(testColl.findOne({a: 1}), {_id: "from prepared transaction", a: 1});
|
|
|
|
assert.commandWorked(
|
|
testDB.adminCommand({configureFailPoint: "skipWriteConflictRetries", mode: "off"}));
|
|
|
|
session.endSession();
|
|
rst.stopSet();
|
|
})();
|