Sobes.tech
Назад к вопросам
Junior — Middle
59

Можешь перечислить виды блокировок, используемых в PostgreSQL, и объяснить их особенности?

Ответ от нейросети

sobes.tech AI

Что хотят услышать интервьюеры:

Нужно показать, что в PostgreSQL блокировки бывают на уровне строк, таблиц и транзакций, и что они решают разные задачи. Важно понимать разницу между lock для конкурирующего доступа и MVCC, который снижает количество конфликтов на чтении. Также полезно знать, какие блокировки чаще возникают автоматически, а какие берутся явно.

Определение:

В PostgreSQL используются несколько типов блокировок. Основные группы — это блокировки таблиц, строк и advisory locks.

Табличные блокировки ограничивают операции над таблицей целиком: например, мешают одновременному изменению структуры или массовым изменениям данных. Строчные блокировки действуют только на конкретные строки и обычно возникают при UPDATE, DELETE или SELECT ... FOR UPDATE. Advisory locks — это прикладные блокировки, которые приложение берет само для синхронизации своих процессов; PostgreSQL не использует их автоматически для данных.

Отдельно важно понимать, что PostgreSQL использует MVCC: обычные SELECT обычно не блокируют UPDATE и наоборот, потому что читают снимок данных. Но при конфликтующих изменениях блокировки все равно появляются.

Пример использования:

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

BEGIN;

SELECT balance
FROM accounts
WHERE id = 1
FOR UPDATE;

UPDATE accounts
SET balance = balance - 100
WHERE id = 1;

COMMIT;

Здесь FOR UPDATE берет блокировку на строку, чтобы другой транзакции было нельзя одновременно изменить ту же запись.

Пояснение кода:

Код показывает типичный сценарий строчной блокировки.

  1. BEGIN открывает транзакцию.
  2. SELECT ... FOR UPDATE читает строку и одновременно ставит на нее блокировку.
  3. Пока транзакция не завершится, другая транзакция не сможет взять конфликтующую блокировку на ту же строку.
  4. UPDATE меняет значение уже под защитой этой блокировки.
  5. COMMIT завершает транзакцию и освобождает блокировку.

Если бы код не использовал FOR UPDATE, две параллельные транзакции могли бы прочитать одинаковый баланс и записать некорректный результат.

Ключевые моменты:

  • PostgreSQL использует блокировки разных уровней: таблицы, строки и advisory locks.
  • Обычные SELECT обычно не блокируют записи благодаря MVCC.
  • Строчные блокировки возникают при UPDATE, DELETE и SELECT ... FOR UPDATE/SHARE.
  • Табличные блокировки нужны для операций, затрагивающих таблицу целиком, особенно DDL.
  • Advisory locks применяются вручную приложением для координации, а не для защиты строк БД.
  • При собеседовании полезно помнить не все названия, а принцип: чем уже блокировка, тем меньше она мешает параллелизму.