Я начал использовать весну с последних нескольких месяцев, и у меня есть вопрос о транзакциях. У меня есть метод java внутри моего пакетного задания spring, который сначала выполняет операцию выбора, чтобы получить первые 100 строк со статусом «НЕ ЗАВЕРШЕНО», и выполняет обновление выбранных строк, чтобы изменить статус на «В ПРОГРЕССЕ». Поскольку я обрабатываю около 10 миллионов записей, я хочу запустить несколько экземпляров моего пакетного задания, и каждый экземпляр имеет несколько потоков. Для одного экземпляра, чтобы убедиться, что два потока не извлекают один и тот же набор записей, я сделал свой метод синхронизированным. Но если я запускаю несколько экземпляров своего пакетного задания (несколько JVM), существует высокая вероятность того, что один и тот же набор записей может быть получен обоими экземплярами, даже если я использую «оптимистическую» или «пессимистическую блокировку» или «выбрать для обновления», поскольку мы не можем блокировать записи во время выбора. Ниже показан пример. Транзакция 1 извлекла 100 записей, а тем временем транзакция 2 также извлекла 100 записей, но если я включу блокировку, транзакция 2 будет ждать, пока транзакция 1 не будет обновлена и зафиксирована. Но транзакция 2 снова делает то же самое обновление.
Есть ли способ весной заставить операцию выбора транзакции 2 дождаться завершения выбора транзакции 1?
Transaction1 Transaction2
fetch 100 records
fetch 100 records
update 100 records
commit
update 100 records
commit
@Transactional
public synchronized List<Student> processStudentRecords(){
List<Student> students = getNotCompletedRecords();
if(null != students && students.size() > 0){
updateStatusToInProgress(students);
}
return student;
}
Примечание. Я не могу сначала выполнить обновление, а затем выбрать. Буду признателен, если будет предложен какой-либо альтернативный подход?