Я использую
- Spring Загрузка 1.4.2
- Spring Данные JPA 1.10.5
- База данных PostgreSQL 9.5
Я хочу иметь метод findOne
с пессимистической блокировкой в моем репозитории данных Spring, который отделен от метода findOne
, который уже предоставлен.
Следуя этому ответу, я написал:
public interface RegistrationRepository extends CrudRepository<Registration, Long> {
@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("select r from Registration r where r.id = ?1")
Registration findOnePessimistic(Long id);
}
Это почти работает.
К сожалению, это не обновляет предыдущий экземпляр моего объекта в кеше менеджера объектов. У меня есть два одновременных запроса, обновляющих статус моей регистрации.
- второй ожидает транзакции первого, кто совершит
- второй не учитывает изменения, сделанные первым.
Следовательно, нарушение поведения.
Любая подсказка, почему @Lock
не из окна обновить диспетчер сущностей?
Update
Вот запрошенный пример кода:
public interface RegistrationRepository extends CrudRepository<Registration, Long> {
@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("select r from registration_table r where r.id = ?1")
Registration findOnePessimistic(Long id);
}
public void RegistrationService {
@Transactional
public void doSomething(long id){
// Both threads read the same version of the data
Registration registrationQueriedTheFirstTime = registrationRepository.findOne(id);
// First thread gets the lock, second thread waits for the first thread to have committed
Registration registration = registrationRepository.findOnePessimistic(id);
// I need this to have this statement, otherwise, registration.getStatus() contains the value not yet updated by the first thread
entityManager.refresh(registration);
registration.setStatus(newStatus);
registrationRepository.save(registration);
}
}