PostgreSQL READ COMMITTED级别下,等待锁的语句能否看到锁释放后的变更?
READ COMMITTED隔离级别下SELECT FOR UPDATE的锁等待与数据读取行为
在READ COMMITTED隔离级别下,普通SELECT语句确实是每个语句生成自己的快照(快照读),但SELECT FOR UPDATE这类加锁查询属于当前读,行为和快照读完全不同:
- 当
SELECT FOR UPDATE因目标行被其他事务锁定而进入等待时,它并不会在等待开始时生成快照; - 一旦持有锁的事务(比如例子中的T1)提交并释放锁,
SELECT FOR UPDATE获取到锁后,会直接读取当前数据库中已提交的最新数据版本。
结合你给出的例子具体说明:
- T1先启动,锁定目标行并修改,持有该行的排他锁;
- T2启动后执行
SELECT FOR UPDATE查询该行,因锁被T1持有进入等待; - T1提交事务,释放排他锁;
- T2获取锁后,会读取到T1提交后的行变更,而非T2开始等待时的旧版本。
本质原因是,加锁查询的设计目标是获取可修改的最新数据,因此会绕过快照机制,直接读取当前已提交的最新状态,这和普通一致性读的快照逻辑区分开。
内容的提问来源于stack exchange,提问作者Ian van der Linde
相关产品推荐
相关产品推荐

