假设两个并发事务在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
语句不会相互死锁(例如,总是按主键的顺序获取行锁)? / p>
如果Postgresql 不能自动防止此类死锁发生,是否有办法修改查询以防止出现这种情况(例如,事实上,如果事实上Postgresql按照id的顺序获取行锁给定,然后一致地排序id应该防止死锁)?
感谢您的帮助!
答案 0 :(得分:3)
抱歉,我有另一个答案,但这是错误的。
文档说明在FOR UPDATE子句之前应用了ORDER BY子句。因此,无论以何种顺序选择行,都可以获取锁(我已经通过测试确认了这一点)。如果您需要以不同的顺序选择它们,可以使用:
SELECT * FROM (SELECT * FROM table ORDER BY id FOR UPDATE) ORDER BY another_column;
您可能想在PostgreSQL mailing list上尝试您的问题。
答案 1 :(得分:0)
来自http://www.postgresql.org/docs/9.1/static/explicit-locking.html:
PostgreSQL会自动检测死锁情况并通过中止其中一个交易来解决它们
该页面使用了一个涉及UPDATE
的示例,在锁定方面相当于SELECT ... FOR UPDATE
。