Search code examples
typescripttypeorm

Is there any reason to use Promise.all in a TypeORM transaction?


I'm using TypeORM to do two operations in one transaction. With no meaning to their order.
Will it actually be faster to use Promise.all, or do the commands queue up internally either way?

Basically, is there a difference in efficiency between the 2 options?

// Option 1
getManager().transaction(async manager => {
  await Promise.all([
    manager.insert(...),
    manager.update(...),
  ]);
});;

// Option 2
getManager().transaction(async manager => {
  await manager.insert(...);
  await manager.update(...);
});

Just to clarify, I know that Promise.all can greatly improve performance in general in JavaScript due to single-threaded logic and event loop and whatnot.
I'm asking specifically about TypeORM and multiple queries in the same transactional manager, since they seem to run in order whether Promise.all is involved or not


Solution

  • Typeorm concurrent transactions with Promise.all can work incorrect because of Promise.all behavior (doesn't wait all promise results).

    await Promise.all(tenDbTxns);
    
    // 5/10 fulfilled
    // 6 rejected ---> typeorm rollback 6/10
    // 4/10 pending and after fulfilled will be committed to database
    

    So as solutions you can use:

    1. sequential query execution:
    const data = [];
    for (const tx of tenDbTxns) {
        const res = await tx;
    
        data.push(tx);
    }
    
    1. concurent execution but with Promise.allSettled (waits all promise results):
    const settled = await Promise.allSettled(tenDbTxns);
    const data = [];
    for (const res of settled) {
        if (res.status === 'rejected') {
            throw res.reason;
        }
    
        data.push(res.value);
    }