我正在运行三个PostgreSQL实例,使用复制(1个主服务器,2个从服务器),这是由两个独立的服务器访问的:
-
第一个(未公开的)服务器基本上遍历特定表中的每一行,并连续更新每个用户的每一个刻度(基于这些资源的生产速率)的特定列(资源)。
-
第二个服务器是一个公开各种功能的公共API,比如花费一定数量的资源。
为了访问和操作数据,我使用了一个ORM库,它允许我编写如下代码:
const resources = await repository.findById(1337);
// some complex computation
resources.iron = computeNewIron(resources.iron);
await repository.save(resources);
当然,当处理ticks的服务器试图更新资源量时,API可能会希望扣除特定数量的资源,这可能会导致任何一个服务器占用一定数量的资源,这是不正确的,基本上是典型的更新异常。
我的问题是,我不仅仅是编写一个“简单”的原子查询
UPDATE table SET iron = iron + 42 WHERE id = :id
. ORM库在内部使用的是一个直接赋值,它不自引用产生类似于
UPDATE table SET iron = 123 WHERE id = :id
以前计算过的金额。
我可以假设,如果使用手动编写的查询,使用自引用原子地递增/递减值,则可以防止出现上述异常。我想知道还有哪些选择可以缓解这个问题。我应该在事务中包装我的SELECT/computation/UPDATE吗?够了吗?