我想,这样当JobInstance
重启工序从上次失败的大块一点向前读取使用Spring Batch的(v3.0.9)重新启动功能。我重新开始正常工作,只要我不使用@StepScope
注解来我myBatisPagingItemReader
bean方法。
我用@StepScope
,这样我可以做后期绑定,以获得JobParameters
我myBatisPagingItemReader
bean方法@Value("#{jobParameters['run-date']}"))
如果我使用@StepScope
注释上myBatisPagingItemReader()
Bean的方法,因为它创造了新的实例(范围=步,名称= 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;
}
}
重新启动实施例,当我使用@Stepscope
批注myBatisPagingItemReader()
,读者获取5条记录,我有块大小(提交间隔)设定为3。
作业实例 - 01 - 工作参数 - 2019年1月2日。 块1: - 过程记录-1 - 过程记录-2 - 过程记录-3 作家 - 写入所有3条记录 块-1提交成功
块2: 过程记录-4 过程记录-5 - 抛出和异常 作业完成,并设置为“失败”状态
现在的任务是再次使用相同的工作参数重新启动。 作业实例 - 01 - 工作参数 - 2019年1月2日。 块1: 过程记录-1 过程记录-2 过程记录-3 作家 - 写入所有3条记录 块-1提交成功
块2: 过程记录-4 过程记录-5 - 抛出和异常 作业完成,并设置为“失败”状态
在@StepScope
豆法myBatisPagingItemReader()
注释创建一个新的实例,请参见下面的日志信息。
在范围=步骤,名称= scopedTarget.myBatisPagingItemReader创建对象
在范围=步骤,名称= scopedTarget.myBatisPagingItemReader注册回调破坏
由于这是新实例,它从开始启动程序,而不是从块-2开始。
MyBatisPagingItemReader.read.count = 3 - 如果我不使用@Stepscope
,从块-2作为重新开始作业步骤设置重新启动。
这里的问题是,你正在返回,而不是完全限定类(ItemReader
),或至少MyBatisPagingItemReader
的ItemStreamReader
。当你使用Spring Batch的的步范围,我们创建了一个代理,允许迟到的初始化。代理是基于方法(在你的情况ItemReader
)的返回类型。你碰到的问题是,因为代理是ItemReader
的,Spring Batch的不知道,你的bean也实现ItemStream
,它是界面,使重启。默认情况下,Spring Batch的自动注册类型ItemStream
为你的所有的bean(你也可以明确自己注册的豆子,但它通常不需要)。
为了解决您的问题,下面应该工作(注意,返回类型的变化):
@Bean
@StepScope
public MyBatisPagingItemReader<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;
}
这就是为什么它是我的建议,如果可能的话,使用@Bean
注释的方法时,你应该返回最具体类型可以允许Spring来帮助尽可能多的。