Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Що таке advisory-блокування і коли воно краще за блокування рядків?

Advisory-блокування (PostgreSQL) - блокування за довільним числом, яке не прив'язане до жодного рядка чи таблиці. База лише гарантує, що один ключ одночасно тримає лише одна сесія; що цей ключ означає - вирішує застосунок.

-- Чекати, доки звільниться
SELECT pg_advisory_lock(42);
-- ... робота ...
SELECT pg_advisory_unlock(42);

-- Не чекати: true, якщо взяли, false - якщо зайнято
SELECT pg_try_advisory_lock(hashtext('import:prices'));

-- Знімається автоматично в кінці транзакції
SELECT pg_advisory_xact_lock(42);

Коли це доречно:

  • Захистити дію, а не рядок: «лише один процес імпорту одночасно», «лише один сервер виконує міграції під час деплою».
  • Блокування того, чого ще немає: не можна взяти FOR UPDATE на рядок, якого ще не створено, а advisory-ключ від, наприклад, email - можна.
  • Без зайвої інфраструктури: коли Redis для розподілених блокувань немає, а PostgreSQL уже є.

Пастки:

  • Сесійні блокування живуть, поки живе з'єднання. Якщо процес «забув» зняти блокування, але з'єднання лишилося в пулі, ключ буде зайнятий безстроково. Транзакційний варіант (_xact_) безпечніший.
  • З PgBouncer у режимі transaction pooling сесійні блокування ламаються: наступний запит може піти іншим з'єднанням.
  • Ключ - число; рядкові ідентифікатори перетворюють хешем, і про можливі колізії варто пам'ятати.

MySQL має схожі GET_LOCK('name', timeout) / RELEASE_LOCK('name') з рядковими іменами.

Докладніше в документації: Advisory-блокування

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання