在带有复制的 typeorm 中,每当我在 EntityManager 事务中时,我是否会访问主实例?

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

我在 AWS RDS 上托管的 Aurora PostgreSQL 数据库中遇到了一些竞争条件问题。与正在发生的情况类似的示例是:

  1. 组 table 有一个列 userEntranceLimits
  2. UserEntrance table 有一个列 userId 和一个列 groupId
  3. 特定组的 UserEntrance 不同用户的 count 不得超过该组的 userEntranceLimits
  4. 在创建新 UserEntrance 的事务中,我检查该组的当前 UserEntrances 计数是否 >= 限制。
  5. 如果不是,我将继续创建一个新的 UserEntrance。
  6. 在极少数情况下,某个组的 UserEntrances 数量会超过其限制。

我最初认为竞争条件是因为只读副本不同步。但是,如果我正确理解 typeorm 代码的 this part,事务将始终在 master 中执行。那正确吗?如果是这种情况,那么我认为竞争条件的实际解决方案是将事务的隔离级别更改为其他内容,例如SERIALIZABLE。我的想法是真的吗?

如果您按照 typeorm docs 中描述的方式使用它,直接调用 entityManager.transaction()@Transaction() 装饰器,并且如果您使用事务提供的连接,则 YES, 事务正在使用 master.

当我调试 typeorm 源时,在开始交易时,entityManager.queryRunnerundefined。因此,根据 EntityManager implementation,将为每个未提供复制模式的事务创建 queryRunner,因此将使用默认值(master)。

所以您的逻辑比事务配置更有可能出现问题。