Как стать автором
Обновить

Комментарии 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 секунда.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий