Search code examples
sqlpostgresqlrace-conditiontypeormamazon-aurora

In typeorm with replication, am I hitting the master instance whenever I am inside an EntityManager transaction?


I am having some race condition issues with an Aurora PostgreSQL DB hosted on AWS RDS. An example similar to what is happening is:

  1. A Group table has a column userEntranceLimits.
  2. A UserEntrance table has a column userId and a column groupId.
  3. The count of a UserEntrance's distinct users for a specific group may not exceed the group's userEntranceLimits.
  4. Inside a transaction for creating a new UserEntrance, I check if the current count of UserEntrances for that group is >= the limit.
  5. If it is not, I proceed to create a new UserEntrance.
  6. In some rare occasions, a group appears with more UserEntrances than its limit.

I initially thought that the race condition was because of out-of-sync read replicas. However, if I am understanding this part of typeorm's code correctly, the transactions will always execute in master. Is that right? If that's the case, then I suppose the actual solution to the race condition is changing the isolation level of the transaction to something else, e.g. SERIALIZABLE. Is any of this that I'm thinking true?


Solution

  • If you use it in way described in typeorm docs calling directly entityManager.transaction() or @Transaction() decorator and if you use connection, provided by transaction, then YES, transactions are using master.

    As I debugged typeorm sources, while starting transaction, entityManager.queryRunner is undefined. So as per EntityManager implementation, queryRunner will be created for each transaction with no replication mode provided, so default (master) will be used.

    So problem is more probable in your logic than in transaction configuration.