在 NestJS 中同步对数据库的多个请求

Synchronize multiple requests to database in NestJS

在我们的 NestJS 应用程序中,我们使用 TypeORM 作为 ORM 来处理数据库 tables 和 typeorm-transactional-cls-hooked 库。

现在我们在同步读取和修改数据库的请求时遇到问题。

样本:

@Transactional()
async doMagicAndIncreaseCount (id) {
    const await { currentCount } = this.fooRepository.findOne(id)

    // do some stuff where I receive new count which I need add to current, for instance 10
    const newCount = currentCount + 10
    

    this.fooRepository.update(id, { currentCount: newCount })
}

当我们从前端同时多次执行这个操作时,最后的计数是错误的。第一个事务读取currentCount然后开始计算,在计算期间开始第二个事务也读取currentCount,第一个事务完成计算并保存新的currentCount,然后第二个事务完成并重写第一笔交易的结果。

我们的目标是在footable上一次只执行一次这个操作,其他请求应该等到

我试过像这样设置 SERIALIZABLE 隔离级别:

@Transactional({ isolationLevel: IsolationLevel.SERIALIZABLE })

确保一次只执行一个请求,但其他请求因错误而失败。你能给我一些解决办法的建议吗?

我从来没有使用过 TypeORM 而且你隐藏了你正在使用的数据库引擎。

无论如何要实现这个目标你需要写锁.

doMagicAndIncreaseCount 伪代码应该类似于

BEGIN TRANSACTION
ACQUIRE WRITE LOCK ON id
READ id RECORD
do computation
SAVE RECORD
CLOSE TRANSACTION

或者,您必须使用一些在数据库引擎上本机原子的操作;前任。 Redis 上的 INCR 操作。

编辑:

阅读 TypeORM find 文档,我可以提出如下建议:

this.fooRepository.findOne({
    where: { id },
    lock: { mode: "pessimistic_write", version: 1 },
})

P.S。查看问题的标签,我猜使用的数据库引擎是 PostgreSQL。