这个问题可以被视为我对 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 theREAD COMMITTED
transaction isolation level and usingORDER BY
and a locking clause to return rows out of order. This is becauseORDER 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 theSELECT
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 theFOR UPDATE
/SHARE
clause in a sub-query, for exampleSELECT * 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/