Spring Batch: Как мы можем предварительно загрузить значения из БД, и это будет использоваться в разделе процессора - PullRequest
0 голосов
/ 13 марта 2019

У меня есть требование, где мне нужно просмотреть несколько таблиц в разделе ItemProcessor. Я не хочу делать несколько вызовов JDBC для каждой строки в разделе ItemProcessor, где это может привести к проблемам с производительностью, когда весенний пакет начал обрабатывать большее количество записей. Каковы обходные пути, чтобы избежать этой ситуации? Есть ли способ предварительно загрузить эти объекты перед ItemProcessor или перед запуском пакета и может ссылаться на него в ItemProcessor?

1 Ответ

0 голосов
/ 15 марта 2019

Вы можете использовать аннотирование вашего метода с @PostConstruct для чтения данных во время инициализации контекста приложения Spring.Сделайте так, чтобы ваш метод чтения ItemReader возвращал значение из списка.Когда весь список будет завершен, верните ноль.Это перестает читать.

@Service
public class YourItemReader implements ItemReader<DomainObject> {

 private int index;

 List<DomainObject> dbRows;

 @PostConstruct
 public void init() {
   List<DomainObject> //read from database
 }


@Override
public DomainObject read(){
        if (null != dbRows && index < dbRows.size()) {
         return dbRows.get(index);
       }
   return null;
}

Если количество записей исчисляется миллионами, я бы посоветовал выполнить чтение из вашей базы данных на основе чанков, а не читать все записи сразу, что может привести к исключению из памяти сборщика мусора.Это можно легко сделать, добавив в таблицу столбец STATUS для отслеживания состояния обрабатываемых записей.Первоначально, когда вы загружаете данные в свою таблицу, установите статус «НЕ ОБРАБОТАНО», а когда ваш ItemReader считывает порцию записей, установите статус «В ПРОЦЕССЕ».Как только ваш ItemProcessor или ItemWriter завершит свою обработку, измените статус с «В ПРОЦЕССЕ» на «ОБРАБОТАНО».Убедитесь, что вы создали метод, который извлекает данные из базы данных как «синхронизированные».Это позволит нескольким потокам не извлекать одни и те же данные из базы данных.

public List<DomainObject> read(){
 return fetchDataFromDb();
}

private synchronized List<DomainObject> fetchProductAssociationData(){
//read your chunk-size of records from database which has status as 'NOT 
PROCESSED' 
 and change the status of the data which is read to 'IN PROGRESS'
return list;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...