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); } }