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

PostgreSQL Serializable隔离级未触发预期报错的疑问

为什么你的Serializable隔离级场景没触发报错?

首先明确:PostgreSQL的Serializable隔离级核心是保证事务执行结果等价于某一种串行执行顺序,不是只要有读写交叉就报错。你的场景完全符合这个要求,所以不会触发冲突。

你的场景为什么合法?

你实际的执行顺序是:

  • 事务1执行select id from test where id = 2(读到id=2)
  • 事务2执行update test SET id = 3 WHERE id = 2
  • 事务2提交
  • 事务1提交

这个并发执行的结果,和先执行事务1、再执行事务2的串行结果完全一致:

  • 串行下事务1读到id=2,事务2完成更新后数据是id=3;
  • 你的并发执行结果也是事务1读到2,最终数据是3。

PostgreSQL的谓词锁机制只会在找不到任何合法串行顺序时才会终止事务,你的场景存在合法串行顺序,所以不会报错。

怎么构造会触发报错的场景?

要构造无法对应任何串行顺序的情况,比如:

  1. 事务1:SELECT id FROM test WHERE id > 1;(假设此时表中只有id=3)
  2. 事务2:INSERT INTO test VALUES(2); 提交事务
  3. 事务1:再次执行SELECT id FROM test WHERE id > 1;,基于两次查询结果做逻辑(比如统计数量)后提交

这时候,事务1第一次读没看到id=2,第二次看到了,但串行执行的话,要么先执行事务1(两次读都看不到2),要么先执行事务2(两次读都能看到2),和实际并发结果矛盾,PostgreSQL就会检测到冲突,终止其中一个事务。

对谓词锁的误解澄清

谓词锁不是用来阻止所有后续写操作,而是阻止那些会破坏"可串行化"的写操作。如果写操作和之前的读操作可以兼容某一种串行执行顺序,就不会触发冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 16:32:04