【发布时间】:2019-02-11 00:41:55
【问题描述】:
我正在运行三个使用复制(1 个主,2 个从)的 PostgreSQL 实例,它们由两个单独的服务器访问:
- 第一个(未公开的)服务器基本上会遍历特定表中的每一行,并在每个滴答声(基于这些资源的生产率)为每个用户持续更新特定的列(资源)。
- 第二个服务器是一个公共 API,它公开了各种功能,例如消耗一定数量的资源。
为了访问和操作数据,我使用了一个 ORM 库,它允许我编写如下代码:
const resources = await repository.findById(1337);
// some complex computation
resources.iron = computeNewIron(resources.iron);
await repository.save(resources);
当然,当处理滴答的服务器试图更新资源量时,API 可能会想要扣除特定数量的资源,这可能导致任何一个服务器假定一定数量的资源,即不正确,基本上是典型的 UPDATE 异常。
我的问题是我不只是在写一个“简单”的原子查询,比如UPDATE table SET iron = iron + 42 WHERE id = :id。 ORM 库在内部使用不自引用各个列的直接赋值,这会产生类似于 UPDATE table SET iron = 123 WHERE id = :id 的内容,其中之前已计算了数量。
我可以假设,如果我使用手动编写的查询,这些查询通过自引用原子地增加/减少值,则可以防止上述异常。我想知道哪些其他选项可以缓解这个问题。我应该将我的 SELECT/computation/UPDATE 包装在事务中吗?够了吗?
【问题讨论】:
标签: database postgresql transactions concurrentmodification