mirror of https://github.com/mongodb/mongo
71 lines
2.8 KiB
JavaScript
71 lines
2.8 KiB
JavaScript
/**
|
|
* This tests that preparing a transaction successfully will update the lastWriteOpTime on
|
|
* secondaries so that the corresponding commitTransaction oplog entry has a correct prevOpTime.
|
|
* The test exercises a failover right after a prepare, so that we have to commit the transaction
|
|
* while talking to a node that was in secondary state when it was prepared. We commit that
|
|
* transaction, then roll back that commit entry, the success of which depends on the prevOpTime
|
|
* being set properly.
|
|
*
|
|
* @tags: [
|
|
* uses_prepare_transaction,
|
|
* uses_transactions,
|
|
* ]
|
|
*/
|
|
(function() {
|
|
"use strict";
|
|
load("jstests/replsets/libs/rollback_test.js");
|
|
load("jstests/core/txns/libs/prepare_helpers.js");
|
|
|
|
const dbName = "test";
|
|
const collName = "prepare_failover_rollback_commit";
|
|
|
|
const rollbackTest = new RollbackTest(collName);
|
|
|
|
let primary = rollbackTest.getPrimary();
|
|
const testDB = primary.getDB(dbName);
|
|
const testColl = testDB.getCollection(collName);
|
|
|
|
// First create the collection for all.
|
|
assert.commandWorked(testColl.insert({"a": "baseDoc"}));
|
|
|
|
const session = primary.startSession();
|
|
const sessionDB = session.getDatabase(dbName);
|
|
const sessionColl = sessionDB.getCollection(collName);
|
|
|
|
session.startTransaction();
|
|
assert.commandWorked(sessionColl.insert({"b": "transactionDoc"}));
|
|
|
|
// Prepare a transaction. This will be replicated to the secondary.
|
|
const prepareTimestamp = PrepareHelpers.prepareTransaction(session);
|
|
|
|
// Do a failover first, without rolling back any of the data from this test. We want the
|
|
// current secondary to become primary and inherit the prepared transaction.
|
|
rollbackTest.transitionToRollbackOperations();
|
|
rollbackTest.transitionToSyncSourceOperationsBeforeRollback();
|
|
rollbackTest.transitionToSyncSourceOperationsDuringRollback();
|
|
rollbackTest.transitionToSteadyStateOperations({skipDataConsistencyChecks: true});
|
|
|
|
// Now set up a rollback scenario for that new primary.
|
|
rollbackTest.transitionToRollbackOperations();
|
|
|
|
// Create a proxy session to reuse the session state of the old primary.
|
|
primary = rollbackTest.getPrimary();
|
|
const newSession1 = new _DelegatingDriverSession(primary, session);
|
|
|
|
// Commit the transaction on this primary. We expect the commit to roll back.
|
|
assert.commandWorked(PrepareHelpers.commitTransaction(newSession1, prepareTimestamp));
|
|
|
|
rollbackTest.transitionToSyncSourceOperationsBeforeRollback();
|
|
rollbackTest.transitionToSyncSourceOperationsDuringRollback();
|
|
rollbackTest.transitionToSteadyStateOperations({skipDataConsistencyChecks: true});
|
|
|
|
// Create a proxy session to reuse the session state of the old primary.
|
|
primary = rollbackTest.getPrimary();
|
|
const newSession2 = new _DelegatingDriverSession(primary, session);
|
|
|
|
// Commit the transaction for all to conclude the test.
|
|
assert.commandWorked(PrepareHelpers.commitTransaction(newSession2, prepareTimestamp));
|
|
|
|
rollbackTest.stop();
|
|
})();
|