问题描述
您好,我正在尝试了解在运行我的应用程序的 3 个实例时与悲观锁相关的问题。 该应用程序有一个春季计划,每 3 小时运行一次,我需要函数内部的业务逻辑 使用@Scheduled 进行注释以仅在其中一个实例中成功运行。
为了实现这一点,在这个函数的开头,我试图像那样锁定表中的特定索引行
@Transactional(propagation = Propagation.REQUIRES_NEW,isolation = Isolation.SERIALIZABLE)
.....
LockTableEntity entity = this.em.find(LockTableEntity.class,1L);
this.em.lock(entity,LockModeType.pessimistic_READ);
//this.em.lock(entity,LockModeType.pessimistic_WRITE); I have tried this as well!!
entity.setDatLock(LocalDateTime.Now());
this.em.merge(entity);
.....
我面临的问题是有时我可以在一个或实例中获得锁定 - 正确抛出异常 LockAcquisitionException 并回滚事务 - 但并不总是在两个实例中正如我所料, 所以只有这 3 个中的一个应该运行到最后!
所以我想知道我做错了什么?我是不是对锁定过程有任何误解?
堆栈:
解决方法
您应该使用 LockTableEntity entity = em.find(LockTableEntity.class,1L,LockMode.PESSIMISTIC_WRITE);
。多次获取同一个排他锁是不可能的。也许您的一项交易超时?