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.