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 — забытая сессионная блокировка приведёт к утечке.