postgresql - 同一张表上的两条 "SELECT FOR UPDATE"语句会导致死锁吗?

标签 postgresql rails-postgresql database-deadlocks

假设两个同时发生的事务在 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 进行排序应该可以防止死锁)?

感谢您的帮助!

最佳答案

抱歉,我有另一个答案,但它错了。

文档指出在 FOR UPDATE 子句之前应用 ORDER BY 子句。因此,无论选择行的顺序如何,都会获取锁(我已经通过测试确认了这一点)。如果您需要以不同的顺序选择它们,您可以使用:

SELECT * FROM (SELECT * FROM table ORDER BY id FOR UPDATE) ORDER BY another_column;

您可能想在 PostgreSQL mailing list 上尝试您的问题.

关于postgresql - 同一张表上的两条 "SELECT FOR UPDATE"语句会导致死锁吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12825663/

相关文章:

ruby-on-rails - Postgres hstore 和 rails 的无效语句

sql - 如何访问 Postgresql 查询中行类型内的字段?

json - 如何在 Swift 中将嵌套的 JSON 字符串解析为对象?

Python 单元测试(使用 SQLAlchemy)不写入/更新数据库?

sql - 如何选择/查找表数据以及最新的关联(多对多)数据

postgresql - 删除子分区表时出现死锁

postgresql - 有没有像 Oracle 那样的 PostgreSQL 加载器?

ruby-on-rails - 我无法使用 View 将 activeRecord 对象保存在旧表中

mysql - 如何解决经常死锁的 MySQL 表?

mysql - 了解 MySQL 中的死锁