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

PostgreSQL含UNION的UPSERT为何偶尔返回空结果?

问题原因分析

出现空结果的核心原因是并发事务竞态条件结合PostgreSQL默认的READ COMMITTED事务隔离级别,具体触发场景如下:

  • 当两个事务(事务A、事务B)同时针对同一个col1值执行该UPSERT语句时:

    1. 事务A执行INSERT ... ON CONFLICT DO NOTHING,此时无已提交的冲突行,插入成功但暂未提交。
    2. 事务B执行INSERT操作时,因事务A的插入未提交,在READ COMMITTED隔离级别下无法看到该行,因此尝试插入,但PostgreSQL会因唯一约束限制,等待事务A提交后再判定冲突。
    3. 事务A提交后,事务B的INSERT触发唯一约束冲突,执行DO NOTHING,此时CTE部分upsert_result为空。
    4. 事务B执行后续的SELECT * FROM table1 WHERE col1=$1时,READ COMMITTED隔离级别下该查询仅能看到事务B启动前已提交的数据,无法读取事务A刚提交的新行,因此该SELECT也返回空。
    5. 最终整个语句的UNION结果为空。
  • 极端场景:若在当前语句执行期间,有其他事务删除了col1对应的行并提交,也可能导致INSERT因暂未感知到删除而触发冲突执行DO NOTHING,后续SELECT时该行已被删除,从而返回空结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 14:01:43