SELECT pid, state, wait_event_type FROM pg_stat_activity;
SELECT mode, granted FROM pg_locks WHERE pid = 1234;

订单服务偶发 500,日志里是 ERROR: deadlock detected,DETAIL 显示 Process 1234 waits for ShareLock,重试能过。这类现象通常不是突然出现的,往前翻半天日志能看到苗头。

追下去是这么回事:两个事务更新同一批行但顺序相反,各自握着对方要的行锁,检测器挑一个牺牲掉,报错的就是被回滚那个,业务侧看到的是随机 500。

这次卡住的地方就在「PG 死锁排查」这一环,单独把它拎出来验证,别和其他改动混在同一次发布里。同类问题如果隔一段时间又出现,多半是某个定时任务或重启流程把改动冲掉了。

把这次用到的命令存进笔记,比记住结论有用,换个环境还能照着走。改完隔一天再看一次,当场正常不代表能稳住。

处理上按这个顺序:按 DETAIL 里的进程号把两个事务的语句捞出来对齐;统一业务代码里多行更新的加锁顺序,再上线;捕获死锁错误码后做整事务重试,别跳过这一单。

确认没问题再收工,压测跑半小时不再出现 deadlock detected,也没有重复生成的订单。

作者 9823189