Это странное требование. По логике, картофель не удаляется до тех пор, пока ваша транзакция не завершится - в конце концов, вы все равно можете откатить транзакцию, и тогда это никогда не происходило. Важным является логический порядок транзакций, и обычно нет ничего плохого в предположении, что транзакция, которая выбрала картошку, произошла логически до транзакции удаления.
Все вышесказанное, если вы все еще настаиваете на своем требовании, вот как вы можете это сделать:
Транзакция удаления просто удаляет картофель с помощью DELETE
, но вы используете измененный запрос для выбора картофеля:
SELECT /* whatever */
FROM potatoes
WHERE /* condition */
FOR SHARE OF potatoes SKIP LOCKED;
В отличие от обычного SELECT
, этот запрос будет устанавливать блокировку SHARE
в каждой выбранной строке. Такие блокировки не конфликтуют друг с другом, поэтому несколько таких запросов могут выбрать один и тот же картофель.
Однако блокировка будет конфликтовать с блокировкой строки EXCLUSIVE
DELETE
, поэтому он не может выбрать такойстрок. Чтобы избежать блокировки при обнаружении такой строки, вы добавляете SKIP LOCKED
, как в моем примере.
Все это не бесплатно: блокировка строки изменяет строку таблицы, поэтому такие запросы будут вызывать как записи, так ичитает.