Комментарии 1
Распределенные блокировки в Liquibase
Liquibase создает таблицу DATABASECHANGELOGLOCK
, в которой содержится одна запись.
| ID | LOCKED | LOCKEDBY | LOCKGRANTED |
|:---|:-------|:---------|:------------|
| 1 | false | null | null |
Блокировка для большинства СУБД происходит следующим образом:
-- acquire lock
SELECT LOCKED FROM DATABASECHANGELOGLOCK WHERE ID = 1;
-- Если false, делаем запрос на взятие блокировки
UPDATE DATABASECHANGELOGLOCK SET LOCKED = true .. WHERE ID = 1;
-- Если UPDATE вернул 0, то блокировку взять не удалось, повторим взятие блокировки через 1 секунду.
-- run migrations..
-- release lock
UPDATE DATABASECHANGELOGLOCK SET LOCKED = false WHERE ID = 1;
В текущем виде этот подход не позволит получить корректно распределенную блокировку для YDB, так как на данный момент UPDATE не возвращает количество обновленных строк. Этот способ становится рабочим, если взятие блокировки делать в транзакции уровня SERIALIZABLE
.
На этом уровне изоляции транзакция фиксирует состояние записи согласно модели MVCC. Если другая транзакция изменяет те же данные, текущая транзакция становится недействительной, поскольку она работала с уже неактуальной версией данных.
-- acquire lock
SELECT LOCKED FROM DATABASECHANGELOGLOCK WHERE ID = 1;
-- Если false, делаем запрос на взятие блокировки
UPDATE DATABASECHANGELOGLOCK SET LOCKED = true .. WHERE ID = 1;
COMMIT;
-- Transaction lock invalidated - означет, что блокировку не удалось взять, кто - то нас обогнал
Клиенты, которые не получили блокировку пытаются получить ее снова с интервалом 1 секунда.
Миграции схемы данных YDB с Flyway и распределенные блокировки