Spring数据CrudRepository和悲观锁

我正在使用

  • Spring Boot 1.4.2
  • Spring Data JPA 1.10.5
  • PostgreSQL 9.5数据库

我希望在我的Spring Data存储库中有一个带悲观锁的findOne方法,该方法与已经提供的findOne方法分开。

根据这个答案,我写道:

 public interface RegistrationRepository extends CrudRepository { @Lock(LockModeType.PESSIMISTIC_WRITE) @Query("select r from Registration r where r.id = ?1") Registration findOnePessimistic(Long id); } 

这几乎可行。

不幸的是,这不会刷新实体管理器缓存中我的实体的先前实例。 我有两个并发请求更新我的注册状态

  • 第二个等待第一个事务的提交
  • 第二个没有考虑第一个的变化。

因此破坏了行为。

任何线索为什么@Lock没有开箱即用刷新实体管理器?

更新

这是请求的示例代码:

 public interface RegistrationRepository extends CrudRepository { @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); } } 

您需要使用Spring为您创建的entityManger transaction

  @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); EntityManager em = EntityManagerFactoryUtils.getTransactionalEntityManager(); em.refresh(registration); registration.setStatus(newStatus); registrationRepository.save(registration); } }