首页 > 解决方案 > 在带有复制的 typeorm 中,每当我在 EntityManager 事务中时,我是否会点击主实例?

问题描述

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

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

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

标签: sqlpostgresqlrace-conditiontypeormamazon-aurora

解决方案


如果您以typeorm 文档中描述的方式使用它直接调用entityManager.transaction()@Transaction()装饰器,并且如果您使用由事务提供的连接,那么的,事务正在使用 master。

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

因此,您的逻辑比事务配置更可能出现问题。


推荐阅读