本文分析在 postgresql 发生的一例死锁问题
表结构和数据
事物隔离级别:读已提交
死锁发生的序列
该问题是典型的 postgresql 死锁问题
问题的原因是数据库会话间对数据库对象的循环上锁在成的
postgresql 的自动死锁检测机制能发现这类循环锁定,解决方法是一旦发生可能的死锁,就强制回滚可能造成死锁的会话的事物
用户在开发应用的过程中需要在特别注意上锁的顺序,否则在并发修改数据时容易造成死锁,导致性能低下
上述用例,如果所有回话加锁的顺序都是从小的 id 到大的 id,则不会发生死锁
同时,也可以使用意向锁来提前锁定需要修改的数据
<a href="https://www.postgresql.org/docs/9.3/static/explicit-locking.html">deadlocks</a>
<a href="https://www.postgresql.org/docs/9.3/static/sql-select.html">select for update</a>