SELECT ... ORDER BY ... FOR UPDATE 语句中的行是否按顺序锁定?
Are the rows locked in order in a SELECT ... ORDER BY ... FOR UPDATE statement?
这个问题可以看作是我对 的评论的后续问题。
我想知道以下语句中的行是否按 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
子句的顺序锁定 与扫描 table 时的顺序相同 。
执行查询并对行进行排序,然后 PostgreSQL 按顺序锁定行。本质上,ORDER BY
发生在 FOR UPDATE
.
之前
现在可能会发生锁定行块,因为并发事务持有锁。如果发生这种情况,并且我们处于 READ COMMITTED
隔离级别,PostgreSQL 等待 直到它可以获得锁,然后 获取当前版本 锁定的行。
如果并发事务修改了定义顺序的列,最终结果将不是ORDER BY
定义的顺序。
这个问题可以看作是我对
我想知道以下语句中的行是否按 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
子句的顺序锁定 与扫描 table 时的顺序相同 。
执行查询并对行进行排序,然后 PostgreSQL 按顺序锁定行。本质上,ORDER BY
发生在 FOR UPDATE
.
现在可能会发生锁定行块,因为并发事务持有锁。如果发生这种情况,并且我们处于 READ COMMITTED
隔离级别,PostgreSQL 等待 直到它可以获得锁,然后 获取当前版本 锁定的行。
如果并发事务修改了定义顺序的列,最终结果将不是ORDER BY
定义的顺序。