你好,我正在尝试理解在运行我的应用程序的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并回滚事务-,但并不总是在两个实例中获得锁,正如我所预期的那样,所以这三个人中只有一个应该一直跑到最后!
所以我想知道我做错了什么?我怎么会误解锁的过程?
堆栈:
- 弹簧套2.5.2
- Hibernate Core 5.4.32
- 数据库MySQL 5.7
- MySQL连接器8.0.25
您应该使用LockTableEntity entity = em.find(LockTableEntity.class, 1L, LockMode.PESSIMISTIC_WRITE);
。不可能多次获取同一个独占锁。也许你的一笔交易超时了?