【发布时间】:2012-10-10 18:10:48
【问题描述】:
假设两个同时事务在 Postgresql DB 上执行以下查询:
交易 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 进行排序应该可以防止死锁)?
感谢您的帮助!
【问题讨论】:
-
这个问题符合dba.SE的要求。
-
IN( .. , ..)集合并不意味着 有序 集合。它只是一个集合(项目的集合),类似于select ...的结果,它是一个(无序的)元组集合。换句话说:评估/执行的顺序是undefined -
这不是您问题的真正答案,但是,如果您害怕死锁,为什么不提升隔离级别
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;这样,第二个 SELECT 将被拒绝。
标签: postgresql rails-postgresql database-deadlocks