Spring Batch: 循环多个Step

在tasklet中返回RepeatStatus.CONTINUABLE只是单纯的重复执行该Step,那么如何重复执行连续的几个的Step?

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.6.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<groupId>kagami</groupId>
	<artifactId>springbatchsample</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>springbatchsample</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<maven.compiler.source>1.8</maven.compiler.source>
		<maven.compiler.target>1.8</maven.compiler.target>
		<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version><!-- https://qiita.com/kagamihoge/items/fbfe90837192fd88fee9 -->
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-batch</artifactId>
		</dependency>
		<dependency>
			<groupId>com.h2database</groupId>
			<artifactId>h2</artifactId>
			<scope>runtime</scope>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.batch</groupId>
			<artifactId>spring-batch-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>
</project>

App.java

package kagami.springbatchsample.deciders;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
import org.springframework.batch.core.job.flow.JobExecutionDecider;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@EnableBatchProcessing
@SpringBootApplication
public class App {

  @Bean
  public Job job(JobBuilderFactory jobs, @Qualifier("s1") Step s1, JobExecutionDecider decider) {
    return jobs
        .get("myJob")
        .incrementer(new RunIdIncrementer())
        .start(s1)
        .next(decider)
          .on("COMPLETED").end()
          .on("CONTINUE").to(s1)
         .end()
        .build();
  }

  @Bean(name = "s1")
  public Step step1(StepBuilderFactory steps) {
    return steps.get("step1").tasklet((stepContribution, chunkContext) -> {
      System.out.println("step 1");
      return RepeatStatus.FINISHED;
    }).build();
  }
  
  @Bean
  public JobExecutionDecider decider() {
    return new JobExecutionDecider() {
      int count = 0;
      @Override
      public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution) {
        if (++count >= 5) {
          return new FlowExecutionStatus("COMPLETED");
        } else {
          return new FlowExecutionStatus("CONTINUE");
        }
      }
    };
  }

  public static void main(String[] args) {
    SpringApplication.run(App.class, args);
  }

}

By using JobExecutionDecider for spring-batch, execute next step You can implement the logic to determine. In the sample code above, count corresponds to that logic.

Then use the implementation of JobExecutionDecider in thejob definition. In the sample code above, if the return value of JobExecutionDecider is " COMPLETED ", it ends, and if it is " CONTINUE ", then step Is executed. As a result, step is repeatedly executed until the condition of count is satisfied.

Below is the run-time log.

2019-06-20 11:50:20.305  INFO 10084 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [step1]
step 1
2019-06-20 11:50:20.347  INFO 10084 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Duplicate step [step1] detected in execution of job=[myJob]. If either step fails, both will be executed again on restart.
2019-06-20 11:50:20.349  INFO 10084 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [step1]
step 1
2019-06-20 11:50:20.356  INFO 10084 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Duplicate step [step1] detected in execution of job=[myJob]. If either step fails, both will be executed again on restart.
2019-06-20 11:50:20.358  INFO 10084 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [step1]
step 1
2019-06-20 11:50:20.366  INFO 10084 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Duplicate step [step1] detected in execution of job=[myJob]. If either step fails, both will be executed again on restart.
2019-06-20 11:50:20.368  INFO 10084 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [step1]
step 1
2019-06-20 11:50:20.375  INFO 10084 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Duplicate step [step1] detected in execution of job=[myJob]. If either step fails, both will be executed again on restart.
2019-06-20 11:50:20.377  INFO 10084 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [step1]
step 1

Duplicate step [step1] detected ...about. As you can see in the log, the same step is used multiple times in a single job, and if either step fails, both will be executed at restart. Since this is a phenomenon, it seems to mean that you should consider it when restarting.

posted @ 2022-01-18 15:51  satire  阅读(1092)  评论(0编辑  收藏  举报