0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 01:21:03 +01:00
mongodb/jstests/sharding/restart_transactions.js
2019-07-27 11:02:23 -04:00

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();
})();