PostgreSQL 出现频繁死锁,通常不是数据库本身有 bug,而是并发访问方式、事务设计或索引/锁粒度出了问题。下面按最常见原因 → 原理 → 解决思路来说明。
这是死锁的第一大原因。
示例:
-- 事务 A
UPDATE account SET balance=balance-100 WHERE id=1;
UPDATE account SET balance=balance+100 WHERE id=2;
-- 事务 B
UPDATE account SET balance=balance-100 WHERE id=2;
UPDATE account SET balance=balance+100 WHERE id=1;
结果:
✅ 解决:
UPDATE account
SET balance = CASE id
WHEN 1 THEN balance-100
WHEN 2 THEN balance+100
END
WHERE id IN (1,2);
事务里做了:
导致:
✅ 解决:
UPDATE orders SET status='done' WHERE user_id=123;
如果 user_id 没有索引:
✅ 解决:
CREATE INDEX idx_orders_user_id ON orders(user_id);
SELECT * FROM account WHERE id=1 FOR UPDATE;
如果:
✅ 解决:
SELECT * FROM account
WHERE id IN (1,2)
ORDER BY id
FOR UPDATE;
更新子表 → 自动锁父表行
更新父表 → 自动锁子表
✅ 解决:
CREATE INDEX idx_child_parent_id ON child(parent_id);
deadlock detected这不是 bug,是保护机制
log_lock_waits = on
deadlock_timeout = 1s
死锁日志会显示:
SELECT * FROM pg_locks;
SELECT * FROM pg_stat_activity;
CREATE EXTENSION pg_stat_statements;
看哪些 SQL 最容易导致锁冲突
PostgreSQL 频繁死锁,几乎一定是:并发事务顺序不一致 + 锁持有太久 + 缺索引
如果你愿意,可以:
我可以直接帮你指出是哪一行在“制造死锁”。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。