Спящие устаревшие объекты
Я сохраняю объекты с помощью метода Spring Data JPA save (Object entity) из многопоточного веб-приложения.
Иногда я нахожу, что когда я загружаю объект из сеанса, используя:
findOne (длинный идентификатор)
Объект, возвращаемый из сеанса, устарел и не отражает последнюю версию из базы данных. Я ТОЛЬКО сохраняю данные из этого приложения и ТОЛЬКО использую один экземпляр интерфейса Spring Data JPA.
Что может быть причиной и как это исправить?
1 ответ
Hibernate использует результат PreparedStatement#executeUpdate для проверки количества обновленных строк. Если ни одна строка не была найдена, она генерирует исключение StaleObjectStateException (при использовании Hibernate API) или OptimisticLockException (при использовании JPA).
Оптимистическая блокировка - это метод управления параллелизмом общего назначения, который работает как для физических транзакций, так и для транзакций уровня приложения.
Таким образом, устаревшие исключения предотвращают явление "потерянного обновления", когда несколько одновременных запросов изменяют одни и те же общие постоянные данные.
В транзакции уровня приложения, после загрузки объекта вы получите логическое повторяемое чтение из-за кэша 1-го уровня (контекст постоянства), но другие пользователи все еще могут изменять вышеупомянутый объект.
Таким образом, вы действительно можете столкнуться с устаревшими объектами, но оптимистический механизм блокировки предотвращает потерю обновлений без каких-либо дополнительных блокировок базы данных и даже работает для долгих разговоров.