Задать вопрос
@artemfisher

Как работают явные блокировки в PostgreSQL?

Добрый день!
Немного запутался.
В PostgreSQL каждая транзакция работает со снимком. Явные блокировки таблиц, строк объявляются внутри транзакции. Следовательно, они тоже работают со снимком. Тогда непонятно как они блокируют таблицы и строки для других транзакций? Получается они блокируют таблицы и строки ТОЛЬКО для операторов в той же транзакции и для подтранзакций текущей транзакции?
  • Вопрос задан
  • 59 просмотров
Подписаться 1 Простой 2 комментария
Пригласить эксперта
Ответы на вопрос 3
Melkij
@Melkij
PostgreSQL DBA
Блокировки строк и блокировки таблиц (и прочих объектов) - два разных механизма. (а serializable изоляция и вовсе частично третий)

Блокировки строк отмечают информацию о себе специальными флагами в заголовке самой заблокированной строки. Запросы, которым нужна блокировка строки сначала проверяют, не отмечена ли эта строка блокировкой, затем проверяют что сейчас с той транзакцией, идентификатор transaction ID которой указан в информации о блокировке. Если транзакция ещё в работе - то начинаем ждать её завершение (или пропускаем строку для skip locked или кидает ошибку если nowait)
Блокировки строк, будь то select for share/for update или пишущие запросы, всегда работают с самой актуальной версией строки.

В то же самое время, любой запрос, трогающий таблицу (даже select) берёт блокировку на эту таблицу соответствующего своим потребностям уровня. Пока не возьмёт блокировку на таблицу - вообще не начнёт выполняться. Информация об этих блокировках размещается в сегменте shared memory памяти, потому доступны всем процессам базы. Если другие бекенды не держат блокировку таблицы конфликтующую с желаемым нашей транзакцией (или ещё только ждут блокировку более высокого уровня), то запрос блокировки удовлетворяется и работа продолжается.
Ответ написан
Комментировать
AshBlade
@AshBlade
Просто хочу быть счастливым
Явные блокировки таблиц, строк объявляются внутри транзакции. Следовательно, они тоже работают со снимком

Откуда такие умозаключения?

Для хранения блокировок используется отдельное место в общей памяти - они доступны всех бэкэндам.

Снимки используются только для определения того, видны ли данные (кортеж) или нет - они локальны для каждого бэкэнда.
Ответ написан
Комментировать
@Jack444
Представь что под капотом есть некая очередь транзакций.
Если несколько транзакций пытаются модифицировать один и тот же ресурс, PostgreSQL обрабатывает их по принципу "первый пришёл — первый обслужен".
Например:
Транзакция A изменяет строку и удерживает блокировку.
Транзакция B пытается изменить ту же строку и переходит в состояние ожидания.
Когда Транзакция A завершается (COMMIT или ROLLBACK), блокировка снимается, и Транзакция B получает доступ.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы