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

Postgres中并发更新/删除同记录时如何避免死锁?

Postgres并发更新/删除死锁问题解答

问题1:是否需要为两条语句都添加SELECT FOR UPDATE?

是的,必须为两条操作都添加SELECT FOR UPDATE的前置锁定逻辑。死锁的核心原因是两个并发进程以相反顺序获取资源锁——比如进程A先拿到更新的排他锁,进程B先拿到删除的排他锁,双方都等待对方释放锁才会继续,最终触发死锁。只有让两个操作都先通过SELECT FOR UPDATE以相同的顺序锁定目标行,才能保证同一时间只有一个进程能拿到锁,另一个进程会进入等待状态,从根源上避免死锁。

问题2:SELECT FOR UPDATE的完整示例

SELECT FOR UPDATE必须在事务上下文中使用,单独执行不会生效。以下是针对你的场景的完整示例:

更新操作的完整流程

-- 开启事务
BEGIN;

-- 先锁定目标行,确保后续更新操作能拿到排他锁
SELECT * FROM table_A WHERE cid = 1 FOR UPDATE;

-- 执行更新操作
UPDATE table_A SET name = 'aaaa' WHERE cid = 1;

-- 提交事务,释放锁
COMMIT;

删除操作的完整流程

-- 开启事务
BEGIN;

-- 先锁定目标行,确保后续删除操作能拿到排他锁
SELECT * FROM table_A WHERE cid = 1 FOR UPDATE;

-- 执行删除操作
DELETE FROM table_A WHERE cid = 1;

-- 提交事务,释放锁
COMMIT;

补充说明

  • SELECT FOR UPDATE会对查询到的行加排他锁,其他进程尝试对这些行加锁(包括更新、删除、其他SELECT FOR UPDATE)时会被阻塞,直到当前事务提交或回滚释放锁。
  • 如果业务中存在批量操作(比如同时操作多条记录),一定要保证所有并发操作都按照相同的排序规则锁定行(比如按cid从小到大排序),这样能避免批量场景下的死锁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 09:01:43