我想使用springbatch(v3.0.9)重启功能 JobInstance
重新启动进程步骤,从最后一个失败的区块点向前读取。只要我不使用 @StepScope
我的注解 myBatisPagingItemReader
bean方法。
我用的是 @StepScope
这样我就可以做后期绑定来获得 JobParameters
在我的 myBatisPagingItemReader
bean方法 @Value("#{jobParameters['run-date']}"))
如果我使用 @StepScope
上的注解 myBatisPagingItemReader()
重新启动的bean方法在创建新示例(scope=step,name=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-作业参数-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-抛出和异常
作业完成并设置为“失败”状态
这个 @StepScope
上的注解 myBatisPagingItemReader()
bean方法创建一个新示例,请参见下面的日志消息。
在scope=step,name=scopedtarget.mybatispagingitemreader中创建对象
在scope=step,name=scopedtarget.mybatispagingitemreader中注册了销毁回调
因为它是新示例,所以它从start开始流程,而不是从chunk-2开始。
如果我不使用 @Stepscope
,当重新启动的作业步骤设置为-mybatispagingitemreader.read.count=3时,它将从chunk-2重新启动。
1条答案
按热度按时间hts6caw31#
这里的问题是,你正在返回一个
ItemReader
而不是完全合格的班级(MyBatisPagingItemReader
)或者至少ItemStreamReader
. 当您使用springbatch的step作用域时,我们会创建一个代理以允许后期初始化。代理基于方法的返回类型(ItemReader
在你的情况下)。您遇到的问题是,因为代理是ItemReader
,spring批不知道你的bean也实现了ItemStream
正是这个接口实现了可重启性。默认情况下,springbatch将自动注册类型为的所有beanItemStream
对于您(您也可以自己显式注册bean,但通常不需要)。为了解决您的问题,应该使用以下方法(注意返回类型的更改):
这就是为什么我建议在可能的情况下
@Bean
对于带注解的方法,应该返回尽可能具体的类型,以允许spring尽可能多地提供帮助。