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
63
64
65
66
67
68
69
70
|
/**
* Utilities for testing retryable writes.
*/
var RetryableWritesUtil = (function() {
/**
* Returns true if the error code is retryable, assuming the command is idempotent.
*
* TODO SERVER-34666: Expose the isRetryableCode() function that's defined in
* src/mongo/shell/session.js and use it here.
*/
function isRetryableCode(code) {
return ErrorCodes.isNetworkError(code) || ErrorCodes.isNotMasterError(code) ||
ErrorCodes.isWriteConcernError(code) || ErrorCodes.isShutdownError(code) ||
ErrorCodes.isInterruption(code);
}
const kRetryableWriteCommands =
new Set(["delete", "findandmodify", "findAndModify", "insert", "update"]);
/**
* Returns true if the command name is that of a retryable write command.
*/
function isRetryableWriteCmdName(cmdName) {
return kRetryableWriteCommands.has(cmdName);
}
const kStorageEnginesWithoutDocumentLocking = new Set(["ephemeralForTest", "mmapv1"]);
/**
* Returns true if the given storage engine supports retryable writes (i.e. supports
* document-level locking).
*/
function storageEngineSupportsRetryableWrites(storageEngineName) {
return !kStorageEnginesWithoutDocumentLocking.has(storageEngineName);
}
/**
* Asserts the connection has a document in its transaction collection that has the given
* sessionId, txnNumber, and lastWriteOptimeTs.
*/
function checkTransactionTable(conn, lsid, txnNumber, ts) {
let table = conn.getDB("config").transactions;
let res = table.findOne({"_id.id": lsid.id});
assert.eq(res.txnNum, txnNumber);
assert.eq(res.lastWriteOpTime.ts, ts);
}
/**
* Asserts the transaction collection document for the given session id is the same on both
* connections.
*/
function assertSameRecordOnBothConnections(primary, secondary, lsid) {
let primaryRecord = primary.getDB("config").transactions.findOne({"_id.id": lsid.id});
let secondaryRecord = secondary.getDB("config").transactions.findOne({"_id.id": lsid.id});
assert.eq(bsonWoCompare(primaryRecord, secondaryRecord),
0,
"expected transaction records: " + tojson(primaryRecord) + " and " +
tojson(secondaryRecord) + " to be the same for lsid: " + tojson(lsid));
}
return {
isRetryableCode,
isRetryableWriteCmdName,
storageEngineSupportsRetryableWrites,
checkTransactionTable,
assertSameRecordOnBothConnections,
};
})();
|