В typeorm с репликацией, попадаю ли я в главный экземпляр всякий раз, когда нахожусь внутри транзакции EntityManager?

#sql #postgresql #race-condition #typeorm #amazon-aurora

#sql #postgresql #состояние гонки #typeorm #amazon-aurora

Вопрос:

У меня возникли некоторые проблемы с условиями гонки с базой данных Aurora PostgreSQL, размещенной на AWS RDS. Пример, похожий на то, что происходит:

  1. В таблице группы есть столбец userEntranceLimits .
  2. В таблице UserEntrance есть столбец userId и столбец groupId .
  3. Количество count отдельных пользователей UserEntrance для определенной группы не может превышать группу userEntranceLimits .
  4. Внутри транзакции для создания нового входа пользователя я проверяю, является ли текущее количество входов пользователей для этой группы>= предел.
  5. Если это не так, я приступаю к созданию нового пользовательского входа.
  6. В некоторых редких случаях появляется группа с большим количеством пользователей, чем ее предел.

Сначала я думал, что состояние гонки связано с несинхронизированными репликами чтения. Однако, если я правильно понимаю эту часть кода typeorm, транзакции всегда будут выполняться в master. Это правильно? Если это так, то я полагаю, что фактическим решением условия гонки является изменение уровня изоляции транзакции на что-то другое, например SERIALIZABLE . Является ли что-нибудь из этого, что я думаю, правдой?

Ответ №1:

Если вы используете его способом, описанным в документах typeorm, вызывая напрямую entityManager.transaction() или @Transaction() декоратор, и если вы используете соединение, предоставляемое транзакцией, тогда ДА, транзакции используют master.

Поскольку я отлаживал источники typeorm при запуске транзакции, entityManager.queryRunner это undefined . Итак, согласно реализации EntityManager, queryRunner будет создан для каждой транзакции без предоставления режима репликации, поэтому будет использоваться default (master).

Таким образом, проблема более вероятна в вашей логике, чем в конфигурации транзакции.