Как работает optimistic блокировка в базе данных
Что проверяют
Понимаете ли вы механику: это не блокировка, а проверка версии в момент записи, плюс обязательная стратегия поведения при конфликте. Без второй части ответ неполный.
Как отвечать
- Идея: конфликты редки, поэтому при чтении строка не блокируется, а запись идёт условным обновлением с проверкой, что данные не менялись.
- Механика: колонка версии, обычно целое число, реже отметка времени. Обновление вида
update goods set qty = ?, version = version + 1 where id = ? and version = ?. Затронуто ноль строк, значит кто-то опередил и транзакцию надо откатывать. - В JPA это поле с аннотацией
@Version. Hibernate сам дописывает условие и поднимает версию, а при нуле строк бросаетOptimisticLockException(в Spring она оборачивается вObjectOptimisticLockingFailureException). Работает и с отсоединённой сущностью, поэтому подход основной для веб-форм. - Обработка конфликта обязательна: перечитать данные и повторить операцию в новой транзакции (после исключения
EntityManagerиспользовать нельзя) либо сказать пользователю, что запись изменили. - Сравнение с пессимистичной:
select for update(LockModeType.PESSIMISTIC_WRITE) выигрывает при частых конфликтах и коротких транзакциях, оптимистичная при редких пересечениях и долгом редактировании.
@Entity
class Product {
@Id Long id;
@Version long version; // значение ведёт провайдер, руками не трогаем
int stock;
}Где спотыкаются
Думают, что оптимистичная блокировка сама разруливает конкуренцию. Она только обнаруживает конфликт. Без повторной попытки или внятного сообщения пользователь теряет введённые данные.
Присваивают версию вручную. Значением управляет провайдер, ручная запись ломает механизм.
Ждут, что правка элемента коллекции поднимет версию владельца. По умолчанию не поднимет, для этого есть OPTIMISTIC_FORCE_INCREMENT на корне агрегата.
Защищают версией бизнес-инвариант вроде остатка на складе. Версия спасает конкретную строку от потерянного обновления, а условие «не уйти в минус» надёжнее выразить как where stock >= ? в самом запросе.