假设两个并行的事务在 Postgresql 数据库上执行以下查询:
事务 A:
SELECT * FROM mytable WHERE id IN (1, 2, 3, 4) FOR UPDATE
事务B:
SELECT * FROM mytable WHERE id IN (6, 3, 2, 1) FOR UPDATE
Postgresql是否会因为以不一致的顺序获取行锁而发生死锁呢?例如,如果Postgresql按照此示例中给定的ID顺序获取行锁,则存在潜在的死锁风险。或者说,Postgresql是否智能地以一种方式获取行锁,使得同一表上同时进行的离散SELECT FOR UPDATE
语句不会相互死锁(例如通过始终按主键顺序获取行锁)?如果Postgresql没有自动防止这种死锁情况发生,那么有没有一种方法可以修改查询以防止这种情况发生(例如,如果实际上Postgresql按照ID的顺序获取行锁,则始终对ID进行排序将防止死锁)?谢谢您的帮助!
IN( .. , ..)
集合并不意味着是一个有序集合。它只是一个集合(项目的集合),类似于select ...
的结果,这是一个(无序)元组集合。换句话说:评估/执行的顺序是未定义的。 - wildplasserSET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
这样,第二个SELECT将被拒绝。 - bortzmeyer