最近几个月,我开始使用Spring框架。我对以下情况下的事务管理器的工作方式有疑问。
场景: 我正在处理Spring批处理,其中ItemReader多次调用以下方法。此方法从“学生”表中获取状态为“未完成”的记录列表,并将这些记录的状态更新为“进行中”。我正在处理1000万条记录,因此计划使用多个线程和多个JVM执行批处理。
目前已实施的解决方案: 我已使该方法同步化,以确保在给定的时间只有一个线程读取记录,以便没有两个线程会尝试获取相同的“未完成”记录。还添加了@Transactional,以便在此方法中发生任何问题时,spring都会回滚更改。
问题: 事务管理如何与多个JVM访问一个数据库一起工作?如果我正在运行2-3个应用程序实例,那么如何确保这些实例不尝试获取状态为“未完成”的相同记录?春天有这个功能吗?
@Transactional
public synchronized List<Student> processStudentRecords(){
List<Student> students = getNotCompletedRecords();
if(null != students && students.size() > 0){
updateStatusToInProgress(students);
}
return student;
}
答案 0 :(得分:0)
要专门解决您的问题:
@Transactional
。 Spring Batch管理事务,使用该批注会引起问题。但是,以上内容未能解决多个JVM的问题。我假设您正在跨多个JVM的处理中使用某种远程分区。如果是这种情况,您的更新查询将类似于UPDATE STUDENTS SET FLAG = 'NOT COMPLETE' WHERE ID > ? AND FLAG IS NULL LIMIT 100
,其中ID是分区范围的开始,而100是您的块大小。
标记完行后,ItemReader
可以通过SELECT * FROM STUDENT WHERE ID > ? AND FLAG = 'NOT COMPLETE'
之类的查询,其中ID是分区范围的开始。
以上技术可让您扩展到多个JVM,同时保留诸如可重新启动性之类的功能。