Транзакционная блокировка без блокировки строк! — 4 июля 2026 г. в 08:40:05.379
Транзакционная блокировка без блокировки строк! Иногда нужно запретить параллельную обработку одного объекта, но подходящей строки для FOR UPDATE ещё может не быть. SELECT pg_advisory_xact_lock(10, 42); pg_advisory_xact_lock создаёт транзакционную пользовательскую блокировку. Первый аргумент удобно использовать как namespace, второй — как id объекта. SELECT pg_advisory_xact_lock(20, user_id); Пока транзакция не завершится, другой процесс с тем же ключом будет ждать. После COMMIT или ROLLBACK блокировка снимается автоматически. SELECT pg_try_advisory_xact_lock(20, user_id); Если ждать нельзя, используй pg_try_advisory_xact_lock: он сразу вернёт true или false, и приложение сможет аккуратно пропустить задачу. BEGIN; SELECT pg_advisory_xact_lock(30, 123); UPDATE invoices SET status = 'paid' WHERE id = 123; COMMIT; advisory lock не блокирует таблицу и не заменяет ограничения БД. Это кооперативная блокировка, поэтому все участники должны использовать один и тот же ключ. Полезно для идемпотентных операций, генерации документов, биллинга, обработки вебхуков и любых мест, где один и тот же объект нельзя обрабатывать параллельно. SQL Ready | #совет

