我正在使用Spring Batch重新启动功能,以便它从上一个失败的点开始读取。只要不对我的@StepScope
bean方法使用myBatisPagingItemReader
批注,重新启动就可以正常工作。
我必须使用@StepScope
,以便我可以使用myBatisPagingItemReader bean方法的输入参数进行后期绑定以获取jobParameters
@Value("#{JobParameters['run-date']}"))
如果我使用@StepScope
,重启将无法进行。
我尝试添加侦听器new JobParameterExecutionContextCopyListener()
以将JobParameters复制到ExecutionContext。
但是,由于没有ItemReader的打开方法,我如何在myBatisPagingItemReader中访问ExecutionContext?
不确定在不使用@StepScope
的情况下运行myBatisPagingItemReader时如何获得对jobParameters的访问吗?请输入任何内容。
在使用@StepScope
时使用新实例(有状态)时,我对spring-batch重新启动的理解是否正确,也不确定。
@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();
}
}
@Component
public class BatchInputReader {
@Bean
//@StepScope
public ItemReader<Model> myBatisPagingItemReader(
SqlSessionFactory sqlSessionFactory) {
MyBatisPagingItemReader<Model> reader = new
MyBatisPagingItemReader<>();
Map<String, Object> parameterValues = new HashMap<>();
// populate parameterValues from jobParameters ??
reader.setSqlSessionFactory(sqlSessionFactory);
reader.setParameterValues(parameterValues);
reader.setQueryId("query");
return reader;
}
}
答案 0 :(得分:0)
您要在带有myBatisPagingItemReader
(@Component
)注释的类中声明一个Spring Bean(BatchInputReader
)。这是不正确的。
您需要做的是在配置类BatchConfig
中将mybatis阅读器声明为bean。完成并用@StepScope
注释Bean之后,您可以按以下方式传递传递作业参数:
@Configuration
@EnableBatchProcessing
public class BatchConfig {
@Bean
@StepScope
public ItemReader<Model> myBatisPagingItemReader(
SqlSessionFactory sqlSessionFactory,
@Value("#{jobParameters['param1']}") String param1,
@Value("#{jobParameters['param2']}") String param2) {
MyBatisPagingItemReader<Model> reader = new
MyBatisPagingItemReader<>();
Map<String, Object> parameterValues = new HashMap<>();
// populate parameterValues from jobParameters ?? => Those can be now accessed from method parameters
reader.setSqlSessionFactory(sqlSessionFactory);
reader.setParameterValues(parameterValues);
reader.setQueryId("query");
return reader;
}
@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();
}
}
在Late Binding of Job and Step Attributes部分中对此有更多详细信息。 BatchInputReader
将保留为空,不再需要。少即是多! :-)
希望这会有所帮助。
答案 1 :(得分:0)
添加到我的问题。我已按照建议将myBatisPagingItemReader()添加到配置了注释的类中。
当我对MyBatisPagingItemReader()使用@Stepscope注释时,重新启动示例,读取器正在读取5条记录,并且我将块大小(commit-interval)设置为3。
作业实例-01-作业参数-01/02/2019。
块1:
-流程记录1
-流程记录2
-流程记录3
writer-写全部3条记录
chunk-1提交成功
chunk-2: 处理记录4 流程记录5-引发和异常 作业完成并设置为“失败”状态
现在,使用相同的作业参数再次重新启动作业。
作业实例-01-作业参数-01/02/2019。
块1:
流程记录1
流程记录2
流程记录3
writer-写全部3条记录
chunk-1提交成功
chunk-2:
流程记录4
流程记录5-引发和异常
作业完成并设置为“失败”状态
请注意:在这里,当我在myBatisPagingItemReader()bean方法上使用@Stepscope注释时,作业将创建一个新实例,请参见下面的日志消息。
在scope = step中创建对象,名称= scopedTarget.myBatisPagingItemReader
在scope = step,name = scopedTarget.myBatisPagingItemReader
中注册的销毁回调
由于它是新实例,因此它从头开始而不是从chunk-2开始。
如果我不使用Stepscope,随着重新启动的作业步骤设置-MyBatisPagingItemReader.read.count = 3,它将从块2重新启动。
我想使用Stepscope使用后期绑定,如果我使用Stepscope,我的myBatisPagingItemReader是否可以从上次失败开始设置read.count以便重新启动工作?
或
如果我不使用@Stepscope,是否可以在myBatisPagingItemReader中获取作业参数?