#11 spring batch: Transition - on(), to(), stop(), fail(), end(), stopAndRestart()

This commit is contained in:
haerong22
2022-06-22 02:33:13 +09:00
parent 01f01ee628
commit d7ba035648
2 changed files with 143 additions and 1 deletions

View File

@@ -13,7 +13,7 @@ import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
//@Configuration
@RequiredArgsConstructor
public class BatchStatusExitStatusConfiguration {

View File

@@ -0,0 +1,142 @@
package io.springbatch.basic.flow;
import lombok.RequiredArgsConstructor;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@RequiredArgsConstructor
public class TransitionConfiguration {
private final JobBuilderFactory jobBuilderFactory;
private final StepBuilderFactory stepBuilderFactory;
/*
Transition
- Flow 내 Step 의 조건부 전환(전이)을 정의
- Job 의 API 설정에서 on(String pattern) 메소드를 호출하면 TransitionBuilder 가 반환되어 Transition Flow 를 구성
- Step 의 종료상태(ExitStatus)가 어떤 pattern 과도 매칭되지 않으면 스프링 배치에서 예외를 발생하고 Job 은 실패
- transition 은 구체적인 것 부터 적용
API
- on(String pattern)
- Step 의 실행 결과로 돌려받는 종료상태(ExitStatus)와 매칭하는 패턴 스키마, BatchStatus 와 매칭하는 것이 아님
- pattern 과 ExitStatus 와 매칭이 되면 다음으로 실행할 Step 을 지정
- 특수문자는 두가지만 허용
- "*" : 0개 이상의 문자와 매칭, 모든 ExitStatus 와 매칭
- "?" : 정확히 1개의 문자와 매칭
- ex) "c*t" 는 "cat"과 "count"에 매칭되고, "c?t"는 "cat" 에는 매칭되지만 "count" 는 매칭되지 않는다.
- to()
- 다음으로 실행할 단계를 지정
- from()
- 이전 단계에서 정의한 Transition 을 새롭게 추가 정의
Job 을 중단하거나 종료하는 Transition API
- Flow 가 실행되면 FlowExecutionStatus 에 상태값이 저장되고 최종적으로 Job 의 BatchStatus 와 ExitStatus 에 반영
- Step 의 BatchStatus 및 ExitStatus 에는 아무런 영향을 주지 않고 Job 의 상태만을 변경
- stop()
- FlowExecutionStatus 가 STOPPED 상태로 종료되는 transition
- Job 의 BatchStatus 와 ExitStatus 가 STOPPED 로 종료
- fail()
- FlowExecutionStatus 가 FAILED 상태로 종료되는 transition
- Job 의 BatchStatus 와 ExitStatus 가 FAILED 로 종료
- end()
- FlowExecutionStatus 가 COMPLETED 상태로 종료되는 transition
- Job 의 BatchStatus 와 ExitStatus 가 COMPLETED 로 종료
- Step 의 ExitStatus 가 FAILED 이더라도 Job 의 BatchStatus 가
COMPLETED 로 종료하도록 가능하고 이 때 Job 의 재시작은 불가능
- stopAndRestart(Step or Flow or JobExecutionDecider)
- stop() transition 과 기본 흐름은 동일
- 특정 step 에서 작업을 중단하도록 설정하면 중단 이전의 Step 만 COMPLETED 로 저장되고
이후의 Step 은 실행되지 않고 STOPPED 상태로 Job 종료
- Job 이 다시 실행 됐을 때 실행해야 할 step 을 restart 인자로 넘기면
이전에 COMPLETED 로 저장된 Step 은 건너뛰고 중단 이후 Step 부터 시작
*/
@Bean
public Job batchJob() {
return jobBuilderFactory.get("batchJob")
.incrementer(new RunIdIncrementer())
.start(step1())
.on("FAILED")
.to(step2())
.on("FAILED")
.stop()
.from(step1())
.on("*")
.to(step3())
.next(step4())
.from(step2())
.on("*")
.to(step5())
.end()
.build();
}
@Bean
public Step step1() {
return stepBuilderFactory.get("step1")
.tasklet((contribution, chunkContext) -> {
System.out.println("step1 was executed");
contribution.setExitStatus(ExitStatus.FAILED);
return RepeatStatus.FINISHED;
})
.build();
}
@Bean
public Step step2() {
return stepBuilderFactory.get("step2")
.tasklet((contribution, chunkContext) -> {
System.out.println("step2 was executed");
contribution.setExitStatus(ExitStatus.FAILED);
return RepeatStatus.FINISHED;
})
.build();
}
@Bean
public Step step3() {
return stepBuilderFactory.get("step3")
.tasklet((contribution, chunkContext) -> {
System.out.println("step3 was executed");
return RepeatStatus.FINISHED;
})
.build();
}
@Bean
public Step step4() {
return stepBuilderFactory.get("step4")
.tasklet((contribution, chunkContext) -> {
System.out.println("step4 was executed");
return RepeatStatus.FINISHED;
})
.build();
}
@Bean
public Step step5() {
return stepBuilderFactory.get("step5")
.tasklet((contribution, chunkContext) -> {
System.out.println("step5 was executed");
return RepeatStatus.FINISHED;
})
.build();
}
}