如何处理两个insert on冲突do update并行postgres查询



我的android设备在春季启动时调用一个端点。当两个设备并行调用时——第一个调用的插入没有完成,第二个调用同时到达db。第一次调用似乎生成了主键,第二次调用看到了冲突,因此尝试更新。第一次调用应该插入,随后的调用应该将值增加1。插入未完成,因此第二次调用将尝试更新该值。因此,它将值更新为null。随后的调用执行value + 1,因此它们再次更新null。如何处理此场景以确保一个调用锁定行,或者如何解决此问题?

insert
into
table1 (primary_key,
quantity)
values(:primary_key,
:qty) on
conflict primary_key do
update
set
quantity = (
select
coalesce(quantity, 1) + :qty
from
table1
where
primary_key = :primary_key)
where
primary_key = :primary_key;

注意-:qty将为1,:primary_key将为代码传递的键。

将数据库插入操作设置为事务(什么是数据库事务?),简而言之,它要么完成所有操作,要么什么都不完成。

你没有发布你的后端代码,但作为参考,它可以在spring引导中完成,像这样https://spring.io/guides/gs/managing-transactions/

解释是您的子查询还没有找到行,因为它对事务还不可见。因此结果是NULL。

用更简单的

来避免竞争条件
INSERT INTO table1 (primary_key, quantity)
VALUES (:primary_key, :qty)
ON CONFLICT (primary_key)
DO UPDATE
SET quantity = coalesce(table1.quantity, 1) + EXCLUDED.quantity;