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

PostgreSQL锁模式冲突含义及RowExclusiveLock阻塞疑问

PostgreSQL锁模式冲突疑问与解答

背景

PostgreSQL官方文档中的锁模式表显示:ROW EXCLUSIVE锁模式与SHARE、SHARE ROW EXCLUSIVE、EXCLUSIVE、ACCESS EXCLUSIVE锁模式冲突,但不与自身冲突。

以下通过两个实操案例提出疑问:

案例1

同时启动事务T1和T2:
T1执行:

my_db=# begin;
BEGIN
my_db=*# update t set color = 'green' where id = 2;
UPDATE 1

T2执行:

my_db=# begin;
BEGIN
my_db=*# update t set color = 'blue' where id = 2;

此时T2被阻塞。查询表t的锁信息仅见RowExclusiveLock和AccessShareLock模式,但根据锁模式表,RowExclusiveLock不与自身冲突。

案例2

重新启动事务T1和T2:
T1执行:

my_db=# begin;
BEGIN
my_db=*# alter table t alter column color TYPE varchar(400);
ALTER TABLE

T2执行:

my_db=# begin;
BEGIN
my_db=*# update t set color = 'black' where id = 2;

T2同样被阻塞,此时查询可见AccessExclusiveLock,而RowExclusiveLock与该模式冲突。

核心疑问

  • PostgreSQL中“锁模式与另一锁模式冲突”具体指什么?
  • 为何RowExclusiveLock不与自身冲突,却会阻塞另一事务?

解答

1. 锁模式冲突的定义

PostgreSQL中,锁模式冲突指的是:当一个事务已持有某一数据库对象(表、行等)的某类锁时,若另一个事务请求同一对象的另一类锁,且两类锁的操作意图互斥,则后一个事务会被阻塞,直到前一个事务释放所持锁。简单说就是两种锁的操作不能同时在同一对象上执行,必须串行处理。

2. RowExclusiveLock不冲突却阻塞的原因

问题出在混淆了表级锁和行级锁的作用范围:

  • 案例1中,两个事务的update确实都在表t上持有表级的RowExclusiveLock,这类表级锁之间确实不冲突——这意味着多个事务可以同时对同一表持有该类表级锁(比如同时更新表中不同行)。但真正导致T2阻塞的是行级排他锁:T1执行update时,会对id=2的行加上行级的排他锁,T2要修改同一行,必须请求该行的排他锁,而行级排他锁是互斥的,所以T2被阻塞。
  • 表级锁的冲突规则和行级锁的互斥逻辑是独立的两个层面,不能混为一谈。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 08:05:10