【问题标题】:Why is my Spring Batch Task launching with the same JOB_INSTANCE_ID for multiple job executions?为什么我的 Spring Batch Task 使用相同的 JOB_INSTANCE_ID 启动多个作业执行?
【发布时间】:2019-12-19 23:04:54
【问题描述】:

我在我们的云平台上运行了一个 Spring Batch 任务,它将使用提供的命令行参数启动,然后跳过第一个步骤的执行,并出现以下错误:

[OUT] The job execution id 992 was run within the task execution 1325
[OUT] Step already complete or not restartable, so no action to execute: 
StepExecution: id=1071, version=3, name=OFileStep, status=COMPLETED, exitStatus=COMPLETED, readCount=0, filterCount=0, writeCount=0 readSkipCount=0, 
writeSkipCount=0, processSkipCount=0, commitCount=1, rollbackCount=0, exitDescription= 

我调查了 Spring Batch 使用的 MySQL 实例中的元数据表,发现 JOB_INSTANCE_ID 在多次执行之间是相同的,每次应该递增 1。

我为作业配置定义的@Bean 是:

@Bean
public Job job() {
    return jobBuilderFactory.get(OTaskConstants.JOB_NAME)
            .listener(listener())
            .incrementer(new RunIdIncrementer())
            .start(dataTransferTaskStep())
            .next(controlMTaskStep())
            .build();
}

有人知道导致这种行为的原因吗?

【问题讨论】:

  • 同一个作业实例可能有多个作业执行,例如当第一次执行失败并且您尝试再次重新运行作业时。如果您使用相同的标识参数启动作业,您将尝试(重新)运行相同的作业实例:如果最后一个作业执行失败,您将执行新的作业,否则 Spring Batch 将告诉您作业实例已完成并且无法再次运行 (JobInstanceAlreadyCompleteException)。但在您的情况下,您正在设置一个RunIdIncrementer,因此您每次都应该获得一个新的作业实例。您如何开展工作?

标签: mysql spring spring-batch cloud-foundry spring-cloud-dataflow


【解决方案1】:

下面一行清楚地说明了一切。

Step already complete or not restartable, so no action to execute: 

表示步骤/作业已完成,无法重新启动。这是 Spring Batch 的行为。为了绕过这个,我们需要传递一个唯一的参数。

在您的情况下,我看到您已经拥有 RunIdIncrementer。现在的问题是为什么它不起作用。

您能否查看 BATCH_JOB_PARMS 表以了解传递给作业的参数?可能是你遗漏了什么。

您也可以使用 SimpleIncrementor。解释见下面代码。

https://docs.spring.io/spring-batch/docs/current/reference/html/index-single.html#JobParametersIncrementer

【讨论】:

    【解决方案2】:

    移除 Job 上的 @Bean 注解。

    当你每次启动/启动应用程序时,它都会在没有参数的情况下启动 Job,因为 spring 尝试加载 bean 并反过来启动批处理作业。

    移除注解并使用 spring scheduler 来调度作业。

    【讨论】:

      【解决方案3】:

      我有同样的问题。下面的代码帮助我解决了它。通过在作业启动器中添加参数,每次运行都会创建一个新的 job_instance_id

      @SpringBootApplication
      public class App implements CommandLineRunner {
          @Autowired
          JobLauncher jobLauncher;
      
          @Autowired
          Job job;
      
          public static void main(String[] args) {
              SpringApplication.run(App.class, args);
          }
      
          @Override
          public void run(String... args) throws Exception {
              JobParameters params = new JobParametersBuilder()
                      .addString("JobID", String.valueOf(System.currentTimeMillis()))
                      .toJobParameters();
              jobLauncher.run(job, params);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2014-12-10
        • 1970-01-01
        • 2012-06-12
        • 1970-01-01
        • 2019-01-05
        • 2020-06-03
        • 2017-11-09
        • 2020-02-25
        • 1970-01-01
        相关资源
        最近更新 更多