Этот вопрос можно рассматривать как продолжение моего комментария к Могут ли два одновременных, но идентичных оператора DELETE вызвать взаимоблокировку?.
Мне интересно, заблокированы ли строки в порядке возрастания my_status
в следующем выражении:
SELECT 1 FROM my_table ORDER BY my_status FOR UPDATE;
На https://www.postgresql.org/docs/9.5/static/sql-select.html, в котором говорится:
Команда
SELECT
может выполняться на уровне изоляции транзакцийREAD COMMITTED
и использоватьORDER BY
и предложение блокировки, чтобы возвращать строки не по порядку. Это потому, чтоORDER BY
применяется первым. Команда сортирует результат, но затем может заблокировать попытку получить блокировку одной или нескольких строк. Как толькоSELECT
разблокируется, некоторые значения упорядоченных столбцов могут быть изменены, что приведет к тому, что эти строки будут выглядеть не по порядку (хотя они упорядочены с точки зрения исходных значений столбцов). При необходимости это можно обойти, поместив предложениеFOR UPDATE
/SHARE
в подзапрос, напримерSELECT * FROM (SELECT * FROM mytable FOR UPDATE) ss ORDER BY column1;
Я не уверен, что это отвечает на мой вопрос. Все это говорит о том, что ORDER BY
применяется первым и что вам нужно поместить FOR UPDATE
в подзапрос, чтобы обойти побочный эффект, заключающийся в том, что фактический порядок вывода может отличаться, если значения столбцов порядка были изменены в то же время. Другими словами, размещение FOR UPDATE
в подзапросе гарантирует, что блокировка произойдет до упорядочения.
Но на самом деле это не говорит нам, действительно ли строки заблокированы в порядке, определяемом предложением ORDER BY
?