Как включить управление транзакциями в приложении Spring, работающем на нескольких JVM - PullRequest
0 голосов
/ 26 февраля 2019

Я начал использовать Spring Framework с последних нескольких месяцев.У меня есть вопрос о том, как работает менеджер транзакций в приведенном ниже сценарии.

Сценарий : я работаю над подпружиненным пакетом, в котором ItemReader вызывает приведенный ниже метод несколько раз.Этот метод выбирает список записей из таблицы «СТУДЕНТЫ», которые находятся в состоянии «НЕ ЗАВЕРШЕНО», и обновляет статус этих записей до «В ПРОЦЕССЕ».Я обрабатываю 10 миллионов записей, поэтому я планирую выполнить мой пакетный процесс, используя несколько потоков и несколько виртуальных машин Java.

Решение, реализованное до сих пор : я синхронизировал этот метод, чтобы убедиться, что только один поток извлекает записи в данный момент времени, чтобы никакие два потока не пытались извлечь одно и то же 'НЕЗАВЕРШЕНО 'записи.Также добавлен @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;
}

1 Ответ

0 голосов
/ 26 февраля 2019

Чтобы конкретно ответить на ваши вопросы:

  1. Не используйте @Transactional для компонентов, используемых Spring Batch.Spring Batch управляет транзакциями, и использование этой аннотации вызовет проблемы.
  2. Чтобы использовать флаг индикатора процесса (как вы предлагаете), вам нужно обновить до выбора.Функция select должна запрашивать только те записи, которые доступны для обработки и которые были помечены.

Вышеизложенное, однако, не решает проблему нескольких 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, сохраняя такие вещи, как перезапуск.

...