You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL并行请求下Update+Insert事务能否正确执行?

结论:无法保证仅一次插入,并发场景下必然出现重复插入问题

原因分析

在READ COMMITTED隔离级别下,你的方案存在致命的并发漏洞:

  • 当多个携带相同参数的请求同时触发,且数据库中还没有目标记录时:
    1. 请求A的事务执行UPDATE,因无匹配行返回受影响行数0,准备执行INSERT;
    2. 同时请求B的事务执行UPDATE,由于A的事务尚未提交,B无法感知到A的未提交操作,同样返回受影响行数0,也进入INSERT流程;
    3. 最终A、B先后提交事务,导致两条完全相同的记录被插入数据库。

核心问题在于:UPDATE仅会对已存在的行加行级锁,当目标行不存在时,不会产生任何锁限制。多个并发事务的UPDATE会毫无阻碍地通过,进而触发重复插入。

可行的替代方案

既然无法使用唯一索引和INSERT ... ON CONFLICT DO UPDATE,可以通过以下方式规避并发问题:

1. 利用数据库专属锁机制

针对业务参数生成唯一标识,用数据库提供的锁函数串行化请求:

  • MySQL:调用GET_LOCK('业务参数唯一标识', 超时时间),获取锁成功后再执行后续逻辑,完成后调用RELEASE_LOCK释放锁;
  • PostgreSQL:调用pg_advisory_lock(业务参数哈希值),将业务参数哈希为整数作为锁标识,执行完逻辑后调用pg_advisory_unlock释放。

2. 引入分布式锁

如果是分布式系统,可以用Redis、ZooKeeper等组件实现分布式锁,针对业务参数加锁,确保同一时间只有一个请求能进入UPDATE→INSERT的逻辑分支。

3. 谨慎提升事务隔离级别(仅辅助作用)

将隔离级别提升至REPEATABLE READ,能避免部分幻读场景,但依然无法解决“无匹配行时UPDATE不锁”的核心问题,不能彻底防止重复插入,仅能作为辅助优化手段。

内容的提问来源于stack exchange,提问作者Alena

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 23:41:02