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

Django使用select_for_update时PostgreSQL出现表锁而非行锁问题

问题原因

  • 你看到的relation类型锁是PostgreSQL的标准意向锁,属于RowExclusiveLock,不是锁住整张表的排他锁。所有行修改类操作(SELECT FOR UPDATE、UPDATE、DELETE等)都会自动在对应表上加这个轻量级表级锁,它只会阻塞ALTER TABLE、DROP TABLE、TRUNCATE这类DDL操作,完全不会阻塞其他事务对表内任意行的读写、行级加锁操作,不影响业务并发。
  • 没有看到tuple类型行锁的常见原因:
    1. PostgreSQL的pg_locks视图默认不会持久化展示无冲突的已持有行锁,只有当行锁出现争用,也就是有其他事务等待这行的锁时,才会在视图中明确展示tuple类型的锁记录
    2. 你在SELECT FOR UPDATE后直接执行了DELETE,被标记为待删除的行的行锁记录会被PostgreSQL优化,不会一直保留在pg_locks的活跃展示列表中

验证方案

你可以通过以下操作确认没有加全表锁:

  1. 运行你给出的事务代码,在sleep阶段新开一个数据库会话
  2. 执行更新同表其他行的SQL,比如UPDATE my_model SET 字段名 = '测试值' WHERE pk = '5678'
  3. 该SQL会立刻执行成功,不会被阻塞,即可证明仅你指定的pk=1234的行被锁定,不存在全表锁

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 06:24:02