Рубрики
Без рубрики

Оптимистичная блокировка MongoDB

Автор оригинала: Vlad Mihalcea.

При переходе с JPA на MongoDB вы начинаете понимать, сколько функций JPA вы ранее принимали как должное. JPA предотвращает “потерянные обновления” как с помощью пессимистической, так и оптимистической блокировки. Оптимистичная блокировка ничего не блокирует, и ее лучше было бы назвать оптимистичной без блокировки или оптимистичным управлением параллелизмом, потому что это то, что она делает в любом случае.

Итак, что значит “потерять обновления”?

Примером из реальной жизни может быть случай, когда несколько фоновых задач обновляют различные атрибуты какой-либо общей сущности.

В нашем примере у нас есть объект продукта с количеством и скидкой, которые решаются двумя отдельными процессорами пакетной обработки.

  1. партия товара загружает Товар с {количество:1, скидка: 0}
  2. запас меняет количество, поэтому у нас есть {количество:5, скидка: 0}
  3. партия со скидкой загружает продукт с {количество:1, скидка: 0}
  4. скидка изменяет скидку, поэтому у нас есть {количество:1, скидка: 15}
  5. Запас сохраняет товар {количество:5, скидка: 0}
  6. Скидка сохраняет товар {количество:1, скидка: 15}
  7. сохраненное количество равно 1, и обновление запасов будет потеряно

В JPA вы можете указать поле @Version (обычно автоматически увеличиваемое число), а Hibernate позаботится об остальном. За кулисами существует механизм безопасности, который проверяет номер обновленных строк при задании определенной версии. Если ни одна строка не была обновлена, значит, версия изменилась и возникает оптимистичное исключение блокировки.

UPDATE Product
SET quantity=1, discount=15
WHERE version=1;

Но если ваше хранилище представляет собой не систему реляционных баз данных, а базу данных NoSQL, вы все равно хотите предотвратить потерю обновлений. К счастью, Spring Data приходит на помощь, поскольку он предоставляет набор аннотаций, ориентированных на документы, среди которых вы можете найти аннотацию @Version с той же семантикой, что и ее аналог JPA.

Также следует использовать механизм автоматической повторной попытки, поскольку оптимистичное исключение блокировки может быть восстановлено. Ему нужно только перезагрузить последний снимок сущности, объединить определенные атрибуты и обновить.

Таким образом, Spring Data предлагает больше, чем поддержку базового репозитория и простую автоматизацию запросов. Надстройка с оптимистичной блокировкой обеспечивает надлежащий уровень согласованности записи, требуемый требованиями вашего приложения.

Код доступен на GitHub