Блокировки PostgreSQL в случаях SELECT FOR UPDATE

Рейтинг: 0Ответов: 1Опубликовано: 25.07.2023

Из документации postgres про явные блокировки, можно увидеть, что существуют блокировки уровня таблиц и блокировки уровня строк

Для блокировок уровня таблиц существует множество различных блокировок, вот одна из них

`ROW SHARE

Команды SELECT FOR UPDATE и SELECT FOR SHARE получают такую блокировку для своих целевых таблиц`

Для блокировок уровня строк так же существует несколько режимов, вот один из них

FOR UPDATE В режиме FOR UPDATE строки, выданные оператором SELECT, блокируются как для изменения

Так в чем же разница ?

В каких случаях команда SELECT FOR UPDATE будет юзать режим уровня таблицы или уровня строк и какая между ними разница

доку прочитал до конца

Ответы

▲ 2Принят

Не "или", а "и". Нужны и будут использованы оба механизма блокировок.

Для SELECT FOR UPDATE нам нужно получить блокировку на каждую интересующую нас строку в таблице - чтобы никто не мог изменить эти строки до завершения этой нашей транзакции. И чтобы подождать других, кто блокировку на эту строку взял раньше. Сам факт "кто-то взял блокировку на эту строку" хранится в самой таблице.

Но прежде этого нам нужно получить RowShareLock на всю таблицу, чтобы никто не мог изменить несовместимым с нашими действиями образом саму таблицу, пока мы с ней работаем. Например, попросту удалить её. А так же, чтобы мы не могли даже начать читать эту таблицу, если кто-то другой держит более строгую блокировку (например, меняет структуру таблицы).

Аналогично для прочих select .. for ...

Касательно блокировки уровня таблицы, не идёт речи о том, что лишь только одна транзакция может взять такую блокировку. Если по таблице Conflicting Lock Modes для каждого нового запроса табличной блокировки ни с кем транзакция не конфликтует, то запрос на блокировку этого уровня будет выдан. Одновременно могут выполняться десятки и сотни конкурентных транзакций с табличной блокировкой, например, RowExclusiveLock уровня. Вот AccessExclusiveLock может быть лишь один, и никто параллельно с ним работать с таблицей не сможет, потому что этот уровень блокировки конфликтует со всеми остальными, включая самого себя.