summaryrefslogtreecommitdiff
path: root/jstests/hooks
diff options
context:
space:
mode:
authorMax Hirschhorn <max.hirschhorn@mongodb.com>2018-12-27 14:37:48 -0500
committerMax Hirschhorn <max.hirschhorn@mongodb.com>2018-12-27 14:37:48 -0500
commit7b72db38ae0121b3df3ac2f5bcbe6ea446ead3cb (patch)
treefcf372bdb0954f50f38a6ca6abe8d2bb5dba2339 /jstests/hooks
parent07ba0c29a19d9648cc913927ecbbbe6240532576 (diff)
downloadmongo-7b72db38ae0121b3df3ac2f5bcbe6ea446ead3cb.tar.gz
SERVER-38182 Avoid calling abortTransaction() after txn committed.
Diffstat (limited to 'jstests/hooks')
-rw-r--r--jstests/hooks/run_check_repl_dbhash_background.js64
1 files changed, 38 insertions, 26 deletions
diff --git a/jstests/hooks/run_check_repl_dbhash_background.js b/jstests/hooks/run_check_repl_dbhash_background.js
index 864f13a0945..5f4be783182 100644
--- a/jstests/hooks/run_check_repl_dbhash_background.js
+++ b/jstests/hooks/run_check_repl_dbhash_background.js
@@ -235,10 +235,23 @@
};
for (let dbName of dbNames) {
+ let result;
+ let clusterTime;
let hasTransientError;
+ // The isTransientError() function is responsible for setting hasTransientError to true.
+ const isTransientError = (e) => {
+ if (e.hasOwnProperty('errorLabels') &&
+ e.errorLabels.includes('TransientTransactionError')) {
+ hasTransientError = true;
+ return true;
+ }
+
+ return false;
+ };
+
do {
- const clusterTime = sessions[0].getOperationTime();
+ clusterTime = sessions[0].getOperationTime();
waitForSecondaries(clusterTime);
for (let session of sessions) {
@@ -246,44 +259,43 @@
{readConcern: {level: 'snapshot', atClusterTime: clusterTime}});
}
- let commitErrorSessionId = undefined;
hasTransientError = false;
try {
- const result = checkCollectionHashesForDB(dbName);
-
- for (let session of sessions) {
- // commitTransaction() calls assert.commandWorked(), which may fail with a
- // WriteConflict error response, which is ignored.
- try {
- session.commitTransaction();
- } catch (e) {
- commitErrorSessionId = session.getSessionId();
- throw e;
- }
- }
-
- for (let mismatchInfo of result) {
- mismatchInfo.atClusterTime = clusterTime;
- results.push(mismatchInfo);
- }
+ result = checkCollectionHashesForDB(dbName);
} catch (e) {
+ // We abort each of the transactions started on the nodes if one of them returns an
+ // error while running the dbHash check.
for (let session of sessions) {
- if ((commitErrorSessionId === undefined) ||
- bsonWoCompare(session.getSessionId(), commitErrorSessionId) !== 0) {
- session.abortTransaction_forTesting();
- }
+ session.abortTransaction_forTesting();
}
- if (e.hasOwnProperty('errorLabels') &&
- e.errorLabels.includes('TransientTransactionError')) {
- hasTransientError = true;
+ if (isTransientError(e)) {
continue;
}
throw e;
}
+
+ // We then attempt to commit each of the transactions started on the nodes to confirm
+ // the data we read was actually majority-committed. If one of them returns an error,
+ // then we still try to commit the transactions started on subsequent nodes in order to
+ // clear their transaction state.
+ for (let session of sessions) {
+ try {
+ session.commitTransaction();
+ } catch (e) {
+ if (!isTransientError(e)) {
+ throw e;
+ }
+ }
+ }
} while (hasTransientError);
+
+ for (let mismatchInfo of result) {
+ mismatchInfo.atClusterTime = clusterTime;
+ results.push(mismatchInfo);
+ }
}
for (let resetFn of resetFns) {