Веб-версияОткрыть в Telegram

ПостPostgreSQL Advisory Locks: синхронизация конкурентных операций!

25 сентября 2026
S
SQL Ready | Базы Данных
PostgreSQL Advisory Locks: синхронизация конкурентных операций! Блокировок строк недостаточно, когда нужно синхронизировать не конкретную запись, а логическую операцию. Например, два воркера одновременно начинают генерацию одного и того же отчёта для пользователя. Даже если результат в итоге сохраняется с UNIQUE(user_id), это не предотвращает двойное выполнение дорогостоящей работы. Для таких случаев PostgreSQL предоставляет advisory locks — блокировки, ключ и семантику которых определяет приложение: SELECT pg_advisory_lock(1001); Если другая сессия запросит lock с тем же ключом, она будет ждать его освобождения. pg_advisory_lock() работает на уровне сессии: блокировка сохраняется до явного pg_advisory_unlock() или завершения сессии: SELECT pg_advisory_unlock(1001); Если критическая секция укладывается в транзакцию, обычно удобнее pg_advisory_xact_lock(): такая блокировка автоматически освобождается при COMMIT или ROLLBACK: BEGIN; SELECT pg_advisory_xact_lock(1, 1001); -- Здесь выполняется операция, которую нужно сериализовать. INSERT INTO reports(user_id, created_at) SELECT 1001, now() WHERE NOT EXISTS ( SELECT 1 FROM reports WHERE user_id = 1001 ); COMMIT; Важно то, что операция, которую нужно защитить от конкурентного выполнения, должна происходить после получения lock и до его освобождения. Если дорогостоящая работа выполняется приложением вне транзакции и может занимать значительное время, держать ради неё долгую транзакцию обычно нежелательно. В таком случае можно использовать session-level advisory lock и гарантированно освобождать его после завершения критической секции. Здесь 1 можно использовать как namespace операции, а 1001 — как идентификатор ресурса: (1, 1001) — generate_report / user 1001 (2, 1001) — recalculate_stats / user 1001 Так независимые операции над одним ресурсом не будут случайно блокировать друг друга. Если воркеру не нужно ждать освобождения lock, есть неблокирующий вариант: SELECT pg_try_advisory_xact_lock(1, 1001); Он сразу вернёт: true — lock получен, выполняем работу false — lock уже удерживается, работу можно пропустить Это удобно для cron-задач и фоновых воркеров, где второй экземпляр работы не должен ждать завершения первого. advisory lock не гарантирует уникальность данных. Он координирует только процессы, которые используют одинаковый протокол блокировок. Инварианты данных по-прежнему должны обеспечиваться самой БД: ALTER TABLE reports ADD CONSTRAINT reports_user_id_key UNIQUE (user_id); PostgreSQL не знает, что означает (1, 1001). Для него это просто ключ блокировки. Поэтому все конкурирующие процессы должны одинаково формировать ключи и захватывать соответствующие locks. 🔥 Advisory locks полезны для генерации артефактов, фоновых задач, пересчётов, cron jobs и других операций, где критическая секция существует на уровне бизнес-логики, а не отдельной строки таблицы. ➡️ SQL Ready | #практика
22 · 1.7K ·

Рядом в ленте

SSQL Ready | Базы ДанныхПочему 5 систем могут потребовать 10 интеграций, а 10 — уже 45? Когда в data stack появляется несколько отдельных инструментов для хранения, обработки и аналитиSSQL Ready | Базы Данных👨‍💻 SQL PostgreSQL Patterns Library — большая коллекция готовых SQL-решений для PostgreSQL! Здесь собраны практические запросы для работы со строками, JSON и ма
это сообщение
SSQL Ready | Базы ДанныхДвойной NOT EXISTS: реляционное деление без подсчёта строк! Задачи вида «найти сущности, удовлетворяющие всем условиям из некоторого набора» встречаются регулярSSQL Ready | Базы Данных🖥 PostgreSQL — разделение и сборка строк! Объединение значений с CONCAT и CONCAT_WS, агрегация строк с STRING_AGG, извлечение отдельных частей с SPLIT_PART, пре
SSQL Ready | Базы ДанныхSQL Ready | Базы Данных@sql_ready · канал · Технологии
17 466подписчиков1 922средний охват поста
Лента площадки Открыть в Telegram

Открытая публичная лента из поискового индекса ChatCrawler — «Google по публичному Telegram»; обновляется по мере обхода площадки. Время — UTC.

Только публичный контент, официальный API Telegram. О проекте · Вопросы · Чего мы не делаем · Убрать страницу из выдачи · Каталог · Поиск · Как мы считаем