JPA PESSIMISTIC_WRITE悲观写锁未按预期生效问题求助
问题排查与解决方案
核心问题分析
你的重复取数问题根源在于查询与数据标记(更新status)的操作不是原子性的,且事务锁的生命周期没有覆盖到关键操作阶段:
- 悲观锁仅在查询时生效,但查询完成后事务立即提交(service层方法返回后事务结束),锁被释放,此时第二个实例仍能查询到同一条status为false的数据。
- 查询后到更新status之间存在空窗期,两个实例可能先后拿到同一条未标记的数据。
- 若MySQL表使用MyISAM存储引擎,会直接忽略行级锁和事务,这也是锁失效的常见原因。
具体解决方案
1. 先确认数据库存储引擎
确保Student表使用InnoDB引擎(MyISAM不支持事务和行级锁),执行SQL检查:
SHOW TABLE STATUS WHERE Name = 'student';
若引擎为MyISAM,执行修改:
ALTER TABLE student ENGINE=InnoDB;
2. 原子化查询+标记操作(推荐方案)
将查询未处理数据和标记为处理中的操作放在同一个事务内,确保锁的生命周期覆盖到标记完成:
步骤1:调整仓库接口
移除仓库方法上的@Transactional,由service层统一管理事务:
@Repository public interface StudentRepository extends CrudRepository<Student,Integer> { @Lock(LockModeType.PESSIMISTIC_WRITE) @Query(value = "SELECT s FROM Student s WHERE s.percentage is null AND s.status = false ORDER BY s.rollid ASC LIMIT 1") Student findFirstStudentWithFalseStatusAndNullPercentage(); }
步骤2:修改service层逻辑
在同一个事务内完成查询加锁、标记status的操作:
@Transactional(isolation = Isolation.SERIALIZABLE) public Student getStudent(){ Student student = studentRepository.findFirstStudentWithFalseStatusAndNullPercentage(); if(student != null){ // 立即标记为处理中,锁将保持到事务提交 student.setStatus(true); studentRepository.save(student); } return student; }
3. 更高效的原子更新方案(替代方案)
直接使用UPDATE语句原子性标记数据,避免依赖悲观锁的时机问题:
步骤1:仓库添加更新方法
@Repository public interface StudentRepository extends CrudRepository<Student,Integer> { @Modifying @Transactional @Query(value = "UPDATE Student s SET s.status = true WHERE s.percentage IS NULL AND s.status = false ORDER BY s.rollid ASC LIMIT 1") int markStudentAsProcessing(); @Query(value = "SELECT s FROM Student s WHERE s.percentage IS NULL AND s.status = true ORDER BY s.rollid ASC LIMIT 1") Student findMarkedStudent(); }
步骤2:service层调用逻辑
@Transactional public Student getStudent(){ int updatedCount = studentRepository.markStudentAsProcessing(); if(updatedCount > 0){ return studentRepository.findMarkedStudent(); } return null; }
额外注意事项
- 确保
@Scheduled定时任务的执行间隔合理,避免短时间内大量请求导致的锁竞争加剧。 - Kafka处理完成后,将status改回false的操作也需保证事务性,避免数据状态异常。
内容的提问来源于stack exchange,提问作者Glitch07
相关产品推荐
相关产品推荐

