使用@StepScope当Spring Batch的重新启动功能不能正常工作

问题描述 投票:0回答:1

我想,这样当JobInstance重启工序从上次失败的大块一点向前读取使用Spring Batch的(v3.0.9)重新启动功能。我重新开始正常工作,只要我不使用@StepScope注解来我myBatisPagingItemReader bean方法。 我用@StepScope,这样我可以做后期绑定,以获得JobParametersmyBatisPagingItemReader 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作为重新开始作业步骤设置重新启动。

spring-batch
1个回答
2
投票

这里的问题是,你正在返回,而不是完全限定类(ItemReader),或至少MyBatisPagingItemReaderItemStreamReader。当你使用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来帮助尽可能多的。

© www.soinside.com 2019 - 2024. All rights reserved.