spring 为什么PESSIMISTIC_WRITE JPA锁不能正常工作?

wgx48brx  于 2023-06-21  发布在  Spring
关注(0)|答案(1)|浏览(122)

我有两个相同的spring Boot 应用程序运行的示例。现在,如果第一个服务器从数据库中获取一行并处理它,并且在处理它的同时,第二个服务器也获取相同的行并开始处理它。但事实不应该是这样。只有一个服务器应该获取它,处理它,然后更新该行。
我试图使用JPA锁开发这个,但由于某种原因,它不起作用。
下面是我的repository接口:

@Repository
public interface StudentRepository extends CrudRepository<Student,Integer> {

@Transactional
    @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")
    public Student findFirstStudentWithFalseStatusAndNullPercentage();

}

有人能帮我一下吗?
P.S:我用的是MySQL数据库
编辑:
所以,基本上我使用Kafka和Sping Boot 。第一个任务是从数据库中获取对象。为此,我有一个函数,它将在每2秒后被调用(使用Scheduled annotation)。然后这个函数将使用我定义的控制器从MySQL数据库中获取student对象(行)。控制器代码:

@Transactional(isolation = Isolation.SERIALIZABLE)
    public Student getStudent(){
        return studentRepository.findFirstStudentWithFalseStatusAndNullPercentage();
    }

此函数将返回从调用它的函数获取的student对象,然后该函数将再次使用JPA将student对象的状态更新为True。最初,所有行的值都是False,它表示对象是否正在处理。一旦它被设置为True,Kafka将进入处理对象的画面,一旦它处理完,线程将更新数据库中的对象,并再次将状态设置为False
请让我知道,如果需要更多的澄清,谢谢!

ru9i0ody

ru9i0ody1#

这只能与支持隔离的事务结合使用,例如:

@Transactional(isolation = Isolation.SERIALIZABLE)
public void log(String message){
    someRepository.findFirstStudentWithFalseStatusAndNullPercentage()
}

参见https://www.baeldung.com/spring-transactional-propagation-isolation
应该由锁“使用”的两个事务都需要标记一个隔离级别
您的Transactional注解需要在执行代码的方法之上,而不是在存储库中。

相关问题