Skip to content
This repository was archived by the owner on Feb 4, 2022. It is now read-only.

Commit bfcf520

Browse files
committed
refactor(transactions): hoist retryCommit and retryTransaction
1 parent 5a2ae77 commit bfcf520

File tree

1 file changed

+62
-63
lines changed

1 file changed

+62
-63
lines changed

lib/sessions.js

Lines changed: 62 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -264,70 +264,8 @@ class ClientSession extends EventEmitter {
264264
* @param {TransactionOptions} [options] Optional settings for the transaction
265265
*/
266266
withTransaction(fn, options) {
267-
const self = this;
268267
const startTime = Date.now();
269-
270-
function retryCommit() {
271-
return self.commitTransaction().catch(err => {
272-
if (
273-
!isWriteConcernTimeoutError(err) &&
274-
(err instanceof MongoError && err.hasErrorLabel('UnknownTransactionCommitResult')) &&
275-
Date.now() - startTime < 120000
276-
) {
277-
return retryCommit();
278-
}
279-
280-
if (
281-
err instanceof MongoError &&
282-
err.hasErrorLabel('TransientTransactionError') &&
283-
Date.now() - startTime < 120000
284-
) {
285-
return retryTransaction();
286-
}
287-
288-
throw err;
289-
});
290-
}
291-
292-
function retryTransaction() {
293-
self.startTransaction(options);
294-
295-
// TODO: should we support callbacks?
296-
return fn(self)
297-
.then(() => {
298-
if (
299-
[
300-
TxnState.NO_TRANSACTION,
301-
TxnState.TRANSACTION_COMMITTED,
302-
TxnState.TRANSACTION_ABORTED
303-
].indexOf(self.transaction.state) !== -1
304-
) {
305-
// Assume user provided function intentionally ended the transaction
306-
return;
307-
}
308-
309-
return retryCommit();
310-
})
311-
.catch(err => {
312-
function maybeRetryOrThrow(err) {
313-
if (
314-
err instanceof MongoError &&
315-
err.hasErrorLabel('TransientTransactionError') &&
316-
Date.now() - startTime < 120000
317-
) {
318-
return retryTransaction();
319-
}
320-
321-
throw err;
322-
}
323-
324-
if (self.transaction.isActive) {
325-
return self.abortTransaction().then(() => maybeRetryOrThrow(err));
326-
}
327-
328-
return maybeRetryOrThrow(err);
329-
});
330-
}
268+
return retryTransaction(this, startTime, fn, options);
331269
}
332270
}
333271

@@ -352,6 +290,67 @@ function isUnknownTransactionCommitResult(err) {
352290
);
353291
}
354292

293+
function retryCommit(session, startTime, fn, options) {
294+
return session.commitTransaction().catch(err => {
295+
if (
296+
!isWriteConcernTimeoutError(err) &&
297+
(err instanceof MongoError && err.hasErrorLabel('UnknownTransactionCommitResult')) &&
298+
Date.now() - startTime < 120000
299+
) {
300+
return retryCommit(session, startTime, fn, options);
301+
}
302+
303+
if (
304+
err instanceof MongoError &&
305+
err.hasErrorLabel('TransientTransactionError') &&
306+
Date.now() - startTime < 120000
307+
) {
308+
return retryTransaction(session, startTime, fn, options);
309+
}
310+
311+
throw err;
312+
});
313+
}
314+
315+
function retryTransaction(session, startTime, fn, options) {
316+
session.startTransaction(options);
317+
318+
return fn(session)
319+
.then(() => {
320+
if (
321+
[
322+
TxnState.NO_TRANSACTION,
323+
TxnState.TRANSACTION_COMMITTED,
324+
TxnState.TRANSACTION_ABORTED
325+
].indexOf(session.transaction.state) !== -1
326+
) {
327+
// Assume user provided function intentionally ended the transaction
328+
return;
329+
}
330+
331+
return retryCommit(session, startTime, fn, options);
332+
})
333+
.catch(err => {
334+
function maybeRetryOrThrow(err) {
335+
if (
336+
err instanceof MongoError &&
337+
err.hasErrorLabel('TransientTransactionError') &&
338+
Date.now() - startTime < 120000
339+
) {
340+
return retryTransaction(session, startTime, fn, options);
341+
}
342+
343+
throw err;
344+
}
345+
346+
if (session.transaction.isActive) {
347+
return session.abortTransaction().then(() => maybeRetryOrThrow(err));
348+
}
349+
350+
return maybeRetryOrThrow(err);
351+
});
352+
}
353+
355354
function endTransaction(session, commandName, callback) {
356355
if (!assertAlive(session, callback)) {
357356
// checking result in case callback was called

0 commit comments

Comments
 (0)