В моем веб-приложении у меня есть несколько потоков, которые могут одновременно обращаться к одним и тем же данным, поэтому я решил реализовать оптимистическую (версионную) и пессимистическую блокировки с помощью Hibernate.
В настоящее время я использую следующий шаблон для блокировки сущности и выполнения операций записи в нее (с помощью диспетчера транзакций Springs и разграничения транзакций с помощью @Transactional):
@Transactional
public void doSomething(entity) {
session.lock(entity, LockMode.UPGRADE);
session.refresh(entity);
// I change the entity itself as well as entites in a relationship.
entity.setBar(...);
for(Child childEntity : entity.getChildren()) {
childEntity.setFoo(...);
}
}
Однако иногда я получаюStaleObjectException
когда @Transactional мигает, что говорит мне, что ChildEntity был изменен одновременно и теперь имеет неправильную версию.
Я предполагаю, что неправильно обновляет entity
и его дочерние элементы так что я работаю с устаревшими данными.Может кто-нибудь указать, как этого добиться?Некоторые мысли обо мне включали очистку контекста постоянства (сеанс) или повторный вызов session.lock(entity, LockMode.READ)
, но я не уверен, что здесь правильно.
Спасибо за вашу помощь!