Если вы хотите заблокировать таблицу в определенной выбранной строке, вам нужно LOCK FIRST
, чтобы они использовали оператор FOR UPDATE / FOR SHARE
.Например, в вашем случае, если вам нужно заблокировать первую строку, вы делаете это:
BEGIN;
LOCK TABLE person IN ROW EXCLUSIVE MODE;
-- BLOCK 1
SELECT * FROM person WHERE name = 'John' and money = 1 FOR UPDATE;
-- BLOCK 2
UPDATE person set name = 'John 2' WHERE name = 'John' and money = 1;
END;
В BLOCK1
перед оператором SELECT
вы ничего не делаете, только сообщая базе данных: «Эй, ябудет что-то делать в этой таблице, поэтому, когда я это сделаю, заблокируйте эту таблицу в этом режиме ".Вы можете выбрать / обновить / удалить любую строку.
Но в BLOCK2
, когда вы используете FOR UPDATE
, вы блокируете эту строку для других транзакций в определенных режимах (подробнее читайте doc подробности).Будет заблокирован до завершения этой транзакции.
Если вам нужен пример, выполните тест и попробуйте выполнить еще один SELECT ... FOR UPDATE
в BLOCK2
до завершения первой транзакции.Он будет ожидать окончания первой транзакции и будет выбирать сразу после нее.
Только блокировка ACCESS EXCLUSIVE блокирует инструкцию SELECT (без FOR UPDATE / SHARE).
Я использую это в функции для контроля подпоследовательностей, и это здорово.Надеюсь, вам понравится.