SHOW transaction_isolation;
BEGIN ISOLATION LEVEL READ COMMITTED;
SELECT id, stock FROM goods WHERE id = 1 FOR UPDATE;

并发扣库存时接口返回 500,日志里是 ERROR: could not serialize access due to concurrent update,重试一次又好了。这类现象通常不是突然出现的,往前翻半天日志能看到苗头。

追下去是这么回事:事务跑在可重复读或串行化隔离级别,提交前发现目标行已被别的事务改过,快照失效只能整体回滚重来,应用层重试才会成功。

围绕「PG 可重复读序列化失败」排查时,命令行跑一遍比在面板里点十次有用,面板会替你做掉不少隐式操作。权限不要一口气开到最大,先加到够用再往上试,范围小才好收。

把复现步骤压到三条以内,交给同事也能跑出来,才算真的定位清楚。改动写完就同步给同事,下一个人踩同一个坑,成本还是你的。

处理上按这个顺序:先查 SHOW transaction_isolation 确认当前隔离级别;热点行冲突交给应用层做整事务重试,别只重试单条 SQL;只读查询别塞进串行化事务里,冲突面能小一半。

确认没问题再收工,同一批并发请求不再报序列化失败,库存扣减结果和流水明细对得上。

作者 9823189