Skip to content

Instantly share code, notes, and snippets.

@vjrngn
Created March 20, 2023 03:05
Show Gist options
  • Save vjrngn/fc46568750f2f468175c2a670b026b06 to your computer and use it in GitHub Desktop.
Save vjrngn/fc46568750f2f468175c2a670b026b06 to your computer and use it in GitHub Desktop.
export async function transactionWithRetry<T>(
manager: EntityManager,
runInTx: (tx: QueryRunner) => Promise<T>,
options: TxOptions = { retries: 10 },
) {
const maxRetries = options.retries;
const backoffInterval = 100;
let tries = 1;
while (tries <= maxRetries) {
const { connection } = manager;
const qr = connection.createQueryRunner();
try {
await qr.startTransaction();
const result = await runInTx(qr);
await qr.commitTransaction();
return result;
} catch (e) {
tries += 1;
await qr.rollbackTransaction();
if (e.code === '23505') {
await new Promise((resolve) => {
setTimeout(() => {
logger.debug('Conflict. Backing off...', { tries });
resolve(null);
}, tries * backoffInterval);
});
} else {
logger.error(`${e.code}: ${e.message}`, e);
throw e;
}
} finally {
await qr.release();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment