2014-09-19 2 views
2

Я сохраняю объекты, используя Spring Data JPA save(Object entity) method из многопоточного веб-приложения.Hibernate Stale Objects

Иногда я нахожу, что, когда я загрузить объект из сеанса с помощью:

findOne(long id)

Объект вернулся из сеанса является устаревшим и не отражает последнюю версию из базы данных. Я ТОЛЬКО сохраняю данные из этого приложения и ТОЛЬКО используя один экземпляр интерфейса Spring Data JPA .

Что может быть причиной этого и как его исправить?

+0

Я проверил кеш, и он использует @Cache (использование = CacheConcurrencyStrategy.READ_WRITE) –

ответ

1

Hibernate использует результат PreparedStatement # executeUpdate для проверки количества обновленных строк. Если ни одна строка не была сопоставлена, она выдает StaleObjectStateException (при использовании Hibernate API) или OptimisticLockException (при использовании JPA).

Optimistic locking - это универсальная технология управления параллелизмом, и она работает как для физических, так и для application-level transactions.

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

В транзакции на уровне приложения после загрузки объекта вы получите логическое повторяемое чтение из-за кеша 1-го уровня (контекст сохранения), но другие пользователи могут все еще модифицировать вышеупомянутый объект.

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

+0

Что вы другими пользователями? У меня есть только одно приложение. –

+0

Доступ к отдельным приложениям может осуществляться несколькими параллельными запросами. –

+0

Да, но все запросы обрабатываются одноэлементным EntityManager. У EntityManager не должно быть никаких устаревших данных. –