summaryrefslogtreecommitdiff
path: root/jstests/sharding/transactions_implicit_abort.js
blob: 09845a804932477231806a7e15081dfd555bf051 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// Verifies mongos will implicitly abort a transaction on all involved shards on a transaction fatal
// error.
//
// @tags: [requires_sharding, uses_transactions, uses_multi_shard_transaction]
(function() {
"use strict";

load("jstests/sharding/libs/sharded_transactions_helpers.js");

const dbName = "test";
const collName = "foo";
const ns = dbName + '.' + collName;

const st = new ShardingTest({shards: 2, mongos: 1, config: 1});

// Set up a sharded collection with one chunk on each shard.

assert.commandWorked(
    st.s.getDB(dbName)[collName].insert({_id: -1}, {writeConcern: {w: "majority"}}));
assert.commandWorked(
    st.s.getDB(dbName)[collName].insert({_id: 1}, {writeConcern: {w: "majority"}}));

assert.commandWorked(st.s.adminCommand({enableSharding: dbName}));
st.ensurePrimaryShard(dbName, st.shard0.shardName);

assert.commandWorked(st.s.adminCommand({shardCollection: ns, key: {_id: 1}}));
assert.commandWorked(st.s.adminCommand({split: ns, middle: {_id: 0}}));
assert.commandWorked(st.s.adminCommand({moveChunk: ns, find: {_id: 1}, to: st.shard1.shardName}));

const session = st.s.startSession();
const sessionDB = session.getDatabase(dbName);

//
// An unhandled error during a transaction should try to abort it on all participants.
//

session.startTransaction();

// Targets Shard0 successfully.
assert.commandWorked(sessionDB.runCommand({find: collName, filter: {_id: -1}}));

// Sharding tests require failInternalCommands: true, since the mongos appears to mongod to be
// an internal client.
assert.commandWorked(st.rs1.getPrimary().adminCommand({
    configureFailPoint: "failCommand",
    mode: "alwaysOn",
    data: {errorCode: ErrorCodes.InternalError, failCommands: ["find"], failInternalCommands: true}
}));

// Targets Shard1 and encounters a transaction fatal error.
assert.commandFailedWithCode(sessionDB.runCommand({find: collName, filter: {_id: 1}}),
                             ErrorCodes.InternalError);

assert.commandWorked(
    st.rs1.getPrimary().adminCommand({configureFailPoint: "failCommand", mode: "off"}));

// The transaction should have been aborted on both shards.
assertNoSuchTransactionOnAllShards(st, session.getSessionId(), session.getTxnNumber_forTesting());
assert.commandFailedWithCode(session.abortTransaction_forTesting(), ErrorCodes.NoSuchTransaction);

st.stop();
})();