我有两个相同的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
。
请让我知道,如果需要更多的澄清,谢谢!
1条答案
按热度按时间ru9i0ody1#
这只能与支持隔离的事务结合使用,例如:
参见https://www.baeldung.com/spring-transactional-propagation-isolation
应该由锁“使用”的两个事务都需要标记一个隔离级别
您的
Transactional
注解需要在执行代码的方法之上,而不是在存储库中。