PostgreSQL Блокировка пробела с помощью SELECT ... FOR UPDATE - PullRequest
4 голосов
/ 12 июля 2020

Существует запрос с Gap Lock , используемый в MySQL / InnoDB:

SELECT id, time, count
FROM table_a
WHERE time
    BETWEEN DATE_SUB(NOW(), INTERVAL 24 HOUR)
    AND NOW()
FOR UPDATE

Он блокирует диапазон time и возвращает недавнюю запись, если она есть (за последние 24 часа). часов). Если нет - сеанс по-прежнему владеет блокировкой в ​​течение последних 24 часов, чтобы безопасно вставить новую запись.

Можно сделать ту же блокировку промежутка на все 24 часа (даже если нет записей ) в PostgreSQL?

1 Ответ

1 голос
/ 13 июля 2020

Способ сделать это в PostgreSQL - использовать уровень изоляции SERIALIZABLE для всех транзакций.

Тогда вам вообще не понадобится FOR UPDATE. PostgreSQL не препятствует вставке строк в промежуток, но если две транзакции одновременно читают и записывают значения в один промежуток, одна из них получит ошибку сериализации и должна будет повторить транзакцию (при второй попытке он обнаружит, что пробел не пустой).

Действующая здесь концепция - это сериализуемость: это приемлемо, если кто-то другой вставляет в пробел , не читая (эта транзакция логически после тот, что у вас SELECT). Но если две транзакции обнаруживают, что промежуток пуст, а затем что-то вставляют, это создаст аномалию, которую предотвращает SERIALIZABLE.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...