【发布时间】:2019-02-04 09:50:03
【问题描述】:
我想使用 Spring Batch (v3.0.9) 重新启动功能,以便当 JobInstance 重新启动时,流程步骤会从最后一个失败的块点向前读取。只要我不对我的myBatisPagingItemReader bean 方法使用@StepScope 注释,我的重启就可以正常工作。
我正在使用@StepScope,以便我可以在我的myBatisPagingItemReader bean 方法@Value("#{jobParameters['run-date']}")) 中进行后期绑定以获取JobParameters
如果我在 myBatisPagingItemReader() bean 方法上使用 @StepScope 注释,则重新启动不起作用,因为它会创建新实例(范围 = 步骤,名称 = scopedTarget.myBatisPagingItemReader)。
如果我使用 stepscope,我的 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;
}
}
当我对myBatisPagingItemReader() 使用@Stepscope 注释时重新启动示例,读取器正在获取5 条记录,并且我将块大小(提交间隔)设置为3。
作业实例 - 01 - 作业参数 - 01/02/2019。
块 1:
- 进程记录-1
- 进程记录-2
- 进程记录-3
writer - 写入所有 3 条记录
chunk-1 提交成功
块 2:
流程记录-4
进程记录 5 - 抛出和异常
作业完成并设置为“失败”状态
现在使用相同的作业参数重新启动作业。
作业实例 - 01 - 作业参数 - 01/02/2019.
块 1:
流程记录-1
流程记录-2
流程记录-3
writer - 写入所有 3 条记录
chunk-1 提交成功
块 2:
流程记录-4
进程记录 5 - 抛出和异常
作业完成并设置为“失败”状态
myBatisPagingItemReader() bean 方法上的 @StepScope 注释创建了一个新实例,请参见下面的日志消息。
在 scope=step 中创建对象,name=scopedTarget.myBatisPagingItemReader
在 scope=step, name=scopedTarget.myBatisPagingItemReader
中注册的销毁回调
由于它是新实例,它从 start 开始进程,而不是从 chunk-2 开始。
如果我不使用@Stepscope,它会在重新启动的作业步骤设置时从块 2 重新启动 - MyBatisPagingItemReader.read.count=3。
【问题讨论】:
-
当您使用
StepScope并且作业第一次尝试失败时,您能否分享重启前步骤执行上下文中read.count的值?你如何重新开始工作?即使有读取器的新实例,该实例也将使用最后(失败)步骤执行中的read.count进行初始化,并从那里继续。我看不出是否使用StepScope会影响可重启性。
标签: spring-batch