Я хочу использовать функцию перезапуска Spring Batch (v3.0.9), чтобы при перезапуске JobInstance
шаг процесса считывался из последней неудачной точки чанка вперед.Мой перезапуск работает нормально, пока я не использую аннотацию @StepScope
к моему методу myBatisPagingItemReader
.
Я использовал @StepScope
, чтобы я мог выполнить позднюю привязку, чтобы получить JobParameters
в моем myBatisPagingItemReader
метод bean @Value("#{jobParameters['run-date']}"))
Если я использую аннотацию @StepScope
для метода myBatisPagingItemReader()
, перезапуск не работает, поскольку он создает новый экземпляр (scope = step, name = scopedTarget.myBatisPagingItemReader).
Если я используюstepsccope, возможно ли, чтобы myBatisPagingItemReader установил read.count с последнего сбоя, чтобы перезагрузка заработала?
Я объяснил эту проблему с помощью приведенного ниже примера.
@Configuration
@EnableBatchProcessing
public class BatchConfig {
@Bean
public Step step1(StepBuilderFactory stepBuilderFactory,
ItemReader<Model> myBatisPagingItemReader,
ItemProcessor<Model, Model> itemProcessor,
ItemWriter<Model> itemWriter) {
return stepBuilderFactory.get("data-load")
.<Model, Model>chunk(10)
.reader(myBatisPagingItemReader)
.processor(itemProcessor)
.writer(itemWriter)
.listener(itemReadListener())
.listener(new JobParameterExecutionContextCopyListener())
.build();
}
@Bean
public Job job(JobBuilderFactory jobBuilderFactory, @Qualifier("step1")
Step step1) {
return jobBuilderFactory.get("load-job")
.incrementer(new RunIdIncrementer())
.start(step1)
.listener(jobExecutionListener())
.build();
}
@Bean
@StepScope
public ItemReader<Model> myBatisPagingItemReader(
SqlSessionFactory sqlSessionFactory,
@Value("#{JobParameters['run-date']}") String runDate)
{
MyBatisPagingItemReader<Model> reader = new
MyBatisPagingItemReader<>();
Map<String, Object> parameterValues = new HashMap<>();
parameterValues.put("runDate", runDate);
reader.setSqlSessionFactory(sqlSessionFactory);
reader.setParameterValues(parameterValues);
reader.setQueryId("query");
return reader;
}
}
Пример перезапуска, когда я использую аннотацию @Stepscope
для myBatisPagingItemReader()
, читатель выбирает 5 записей, и у меня есть размер чанка (интервал фиксации) установлен на 3.
Экземпляр задания - 01 - Параметр задания - 01/02 / 2019.
chunk-1:
- запись процесса-1
- запись процесса-2
- запись процесса-3
запись - запись всех 3 записей
успешное принятие фрагмента-1
фрагмент-2:
запись процесса-4
запись процесса-5- Броски и исключение
Задание завершено и установлено состояние «СБОЙ»
Теперь задание перезапускается снова с использованием того же параметра задания.
Экземпляр задания - 01 - Параметр задания - 01/02/2019.
chunk-1:
запись процесса-1
запись процесса-2
запись процесса-3
Writer - запись всех 3 записей
успешное принятие фрагмента-1
chunk-2:
запись процесса-4
запись процесса-5 - выбросы и исключение
Задание завершено и установлено в состояние «СБОЙ»
Аннотация @StepScope
к методу myBatisPagingItemReader()
создает новый экземпляр, см. Ниже сообщение журнала.
Создание объекта в scope = step, name = scopedTarget.myBatisPagingItemReader
Зарегистрированный обратный вызов уничтожения в scope = step, name= scopedTarget.myBatisPagingItemReader
Поскольку это новый экземпляр, он запускает процесс с начала, а не с чанка-2.
Если я не использую @Stepscope
, он перезапускается с чанка-2, когда устанавливается перезапущенный шаг задания - MyBatisPagingItemReader.read.count = 3.