mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 01:21:03 +01:00
172 lines
5.1 KiB
JavaScript
172 lines
5.1 KiB
JavaScript
/**
|
|
* Verify the states that a multi-statement transaction can be restarted on at the active
|
|
* transaction number for servers in a sharded cluster.
|
|
*
|
|
* @tags: [requires_sharding, uses_transactions, uses_prepare_transaction]
|
|
*/
|
|
(function() {
|
|
"use strict";
|
|
|
|
const collName = "restart_transactions";
|
|
|
|
function runTest(routerDB, directDB) {
|
|
// Set up the underlying collection.
|
|
const routerColl = routerDB[collName];
|
|
assert.commandWorked(
|
|
routerDB.createCollection(routerColl.getName(), {writeConcern: {w: "majority"}}));
|
|
|
|
//
|
|
// Can restart a transaction that has been aborted.
|
|
//
|
|
|
|
let txnNumber = 0;
|
|
assert.commandWorked(directDB.runCommand({
|
|
find: collName,
|
|
txnNumber: NumberLong(txnNumber),
|
|
autocommit: false,
|
|
startTransaction: true,
|
|
}));
|
|
assert.commandWorked(directDB.adminCommand(
|
|
{abortTransaction: 1, txnNumber: NumberLong(txnNumber), autocommit: false}));
|
|
|
|
assert.commandWorked(directDB.runCommand({
|
|
find: collName,
|
|
txnNumber: NumberLong(txnNumber),
|
|
autocommit: false,
|
|
startTransaction: true
|
|
}));
|
|
|
|
//
|
|
// Cannot restart a transaction that is in progress.
|
|
//
|
|
|
|
txnNumber++;
|
|
assert.commandWorked(directDB.runCommand({
|
|
find: collName,
|
|
txnNumber: NumberLong(txnNumber),
|
|
autocommit: false,
|
|
startTransaction: true
|
|
}));
|
|
|
|
assert.commandFailedWithCode(directDB.runCommand({
|
|
find: collName,
|
|
txnNumber: NumberLong(txnNumber),
|
|
autocommit: false,
|
|
startTransaction: true
|
|
}),
|
|
50911);
|
|
|
|
//
|
|
// Cannot restart a transaction that has completed a retryable write.
|
|
//
|
|
|
|
txnNumber++;
|
|
assert.commandWorked(directDB.runCommand(
|
|
{insert: collName, documents: [{x: txnNumber}], txnNumber: NumberLong(txnNumber)}));
|
|
|
|
assert.commandFailedWithCode(directDB.runCommand({
|
|
find: collName,
|
|
txnNumber: NumberLong(txnNumber),
|
|
autocommit: false,
|
|
startTransaction: true
|
|
}),
|
|
50911);
|
|
|
|
//
|
|
// Cannot restart a transaction that has been committed.
|
|
//
|
|
|
|
txnNumber++;
|
|
assert.commandWorked(directDB.runCommand({
|
|
find: collName,
|
|
txnNumber: NumberLong(txnNumber),
|
|
autocommit: false,
|
|
startTransaction: true
|
|
}));
|
|
assert.commandWorked(directDB.adminCommand({
|
|
commitTransaction: 1,
|
|
txnNumber: NumberLong(txnNumber),
|
|
autocommit: false,
|
|
writeConcern: {w: "majority"}
|
|
}));
|
|
|
|
assert.commandFailedWithCode(directDB.runCommand({
|
|
find: collName,
|
|
txnNumber: NumberLong(txnNumber),
|
|
autocommit: false,
|
|
startTransaction: true
|
|
}),
|
|
50911);
|
|
|
|
//
|
|
// Cannot restart a transaction that has been prepared.
|
|
//
|
|
|
|
txnNumber++;
|
|
assert.commandWorked(directDB.runCommand({
|
|
find: collName,
|
|
txnNumber: NumberLong(txnNumber),
|
|
autocommit: false,
|
|
startTransaction: true
|
|
}));
|
|
assert.commandWorked(directDB.adminCommand(
|
|
{prepareTransaction: 1, txnNumber: NumberLong(txnNumber), autocommit: false}));
|
|
|
|
assert.commandFailedWithCode(directDB.runCommand({
|
|
find: collName,
|
|
txnNumber: NumberLong(txnNumber),
|
|
autocommit: false,
|
|
startTransaction: true
|
|
}),
|
|
50911);
|
|
|
|
assert.commandWorked(directDB.adminCommand(
|
|
{abortTransaction: 1, txnNumber: NumberLong(txnNumber), autocommit: false}));
|
|
|
|
//
|
|
// Cannot restart a transaction that has been aborted after being prepared.
|
|
//
|
|
|
|
txnNumber++;
|
|
assert.commandWorked(directDB.runCommand({
|
|
find: collName,
|
|
txnNumber: NumberLong(txnNumber),
|
|
autocommit: false,
|
|
startTransaction: true
|
|
}));
|
|
assert.commandWorked(directDB.adminCommand(
|
|
{prepareTransaction: 1, txnNumber: NumberLong(txnNumber), autocommit: false}));
|
|
assert.commandWorked(directDB.adminCommand(
|
|
{abortTransaction: 1, txnNumber: NumberLong(txnNumber), autocommit: false}));
|
|
|
|
assert.commandFailedWithCode(directDB.runCommand({
|
|
find: collName,
|
|
txnNumber: NumberLong(txnNumber),
|
|
autocommit: false,
|
|
startTransaction: true
|
|
}),
|
|
50911);
|
|
}
|
|
|
|
const st = new ShardingTest({shards: 1, mongos: 1, config: 1});
|
|
|
|
// Directly connect to the shard primary to simulate internal retries by mongos.
|
|
const shardDBName = "test";
|
|
const shardSession = st.rs0.getPrimary().startSession({causalConsistency: false});
|
|
const shardDB = shardSession.getDatabase(shardDBName);
|
|
|
|
runTest(st.s.getDB(shardDBName), shardDB);
|
|
|
|
// TODO SERVER-36632: Consider allowing commands in a transaction to run against the config or
|
|
// admin databases, excluding special collections.
|
|
//
|
|
// Directly connect to the config sever primary to simulate internal retries by mongos.
|
|
// const configDBName = "config";
|
|
// const configSession = st.configRS.getPrimary().startSession({causalConsistency: false});
|
|
// const configDB = configSession.getDatabase(configDBName);
|
|
//
|
|
// runTest(st.s.getDB(configDBName), configDB);
|
|
|
|
st.stop();
|
|
})();
|