sql - SELECT ... ORDER BY ... FOR UPDATE 语句中的行是否按顺序锁定?

标签 sql postgresql postgresql-9.5 database-deadlocks

这个问题可以被视为我对 Can two concurrent but identical DELETE statements cause a deadlock? 的评论的后续问题。 .

我想知道以下语句中的行是否按 my_status 升序锁定:

SELECT 1 FROM my_table ORDER BY my_status FOR UPDATE;

https://www.postgresql.org/docs/9.5/static/sql-select.html 有一个有趣的评论其中说:

It is possible for a SELECT command running at the READ COMMITTED transaction isolation level and using ORDER BY and a locking clause to return rows out of order. This is because ORDER BY is applied first. The command sorts the result, but might then block trying to obtain a lock on one or more of the rows. Once the SELECT unblocks, some of the ordering column values might have been modified, leading to those rows appearing to be out of order (though they are in order in terms of the original column values). This can be worked around at need by placing the FOR UPDATE/SHARE clause in a sub-query, for example

SELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss ORDER BY column1;

我不确定这是否能回答我的问题。所有这一切都表明,首先应用 ORDER BY 并且您需要将 FOR UPDATE 放入子查询中,以解决实际输出顺序可能不同的副作用,如果同时订单列的值已更改。换句话说,将 FOR UPDATE 放入子查询中可确保锁定发生在排序之前。

但这并不能真正告诉我们行是否实际上按照 ORDER BY 子句确定的顺序锁定?

最佳答案

行按 ORDER BY 子句与扫描表时的顺序锁定。

执行查询并对行进行排序,然后 PostgreSQL 按顺序锁定行。本质上,ORDER BY 发生在 FOR UPDATE 之前。

现在,由于并发事务持有锁,锁定行可能会发生阻塞。如果发生这种情况,并且我们处于READ COMMITTED隔离级别,PostgreSQL等待直到它可以获得锁,然后获取当前版本它锁定的行。

如果并发事务修改了定义排序的列,则最终结果将不会按照ORDER BY定义的顺序。

关于sql - SELECT ... ORDER BY ... FOR UPDATE 语句中的行是否按顺序锁定?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51972202/

相关文章:

mysql - 嵌套数据使用什么表结构?

postgresql - 方法 [] 的签名不适用于参数类型

mysql - 如何搜索内容但跳过方括号内的内容?

mysql - 使用两个 key 检索尽可能多的数据,其中一个 key 已损坏

django - 将现有的 auth.User 数据迁移到新的 Django 1.5 自定义用户模型?

出现错误时 PostgreSQL 不返回完整的响应

sql - 将具有多个属性的行转换为每行具有一个属性的行

json - 如何将 to_jsonb 用作 row_to_jsonb?关于 "how much"的详细信息在哪里?

postgresql - Postgres SET UNLOGGED 需要很长时间

sql - 使用 3 个不同的索引选择一系列行