Gymterview
senior

Что такое Advisory Locks и когда их использовать?

Advisory Locks (рекомендательные блокировки) — это механизм блокировок на уровне приложения. PostgreSQL предоставляет инфраструктуру, а семантику определяет приложение. Они не связаны ни с какими объектами базы данных.

Пример
-- Блокировка на уровне сессии (удерживается до явного освобождения или отключения)
SELECT pg_advisory_lock(12345);
-- ... выполняем критическую секцию ...
SELECT pg_advisory_unlock(12345);

-- Блокировка на уровне транзакции (освобождается при COMMIT/ROLLBACK)
BEGIN;
SELECT pg_advisory_xact_lock(12345);
-- ... работаем ...
COMMIT;  -- блокировка автоматически освобождена

-- Неблокирующие варианты (возвращают true/false)
SELECT pg_try_advisory_lock(12345);

-- Разделяемые (shared) advisory locks
SELECT pg_advisory_lock_shared(12345);

Типичные применения

Пример
-- 1. Предотвращение параллельного выполнения batch-процесса
SELECT pg_try_advisory_lock(hashtext('daily_report_generation'));
-- Если true — выполняем, иначе — уже запущен

-- 2. Блокировка обработки конкретной сущности
SELECT pg_advisory_xact_lock(client_id) FROM clients WHERE id = 42;

-- 3. Двухпараметровая блокировка (пространство имён)
SELECT pg_advisory_lock(1, 42);  -- (тип операции, ID сущности)

Преимущества перед SELECT FOR UPDATE

  • Не привязаны к строкам таблицы — можно блокировать абстрактные ресурсы
  • Быстрее для сценариев, не требующих блокировки конкретных строк
  • Полезны для координации между различными процессами приложения

Advisory locks потребляют разделяемую память, ограничение задаётся параметром max_locks_per_transaction.

На собеседовании: advisory locks — это продвинутая тема. Расскажите конкретный сценарий: «предотвращение дублирования batch-задач» или «блокировка обработки клиента без FOR UPDATE». Упомяните разницу между сессионными и транзакционными advisory locks — забытая сессионная блокировка приведёт к утечке.