스프링 배치에서는 현재 Job 또는 Step의 상태를 나타내는 status들이 존재합니다.
BatchStatus와 ExitStatus는 그러한 status의 종류들 이라고 보시면 됩니다.
BatchStatus와 ExitStatus가 살짝 헷갈릴 수 있는데, spring docs에 따르면 다음과 같은 차이점이 있다고 합니다.
정확하지 않을 수도 있지만, 번역을 해보면 BatchStatus는 Job과 Step 모두의 상태를 나타내기 위해 사용되고, ExitStatus는 step이 끝난 이후의 상태를 나타낸다는 것 같습니다.
(근데, 찾아보니 Job 또한 ExitStatus를 가지고 있습니다. BatchStatus는 실행의 상태, ExitStatus는 실행 후 실행결과의 상태 정도로 이해하면 될 것 같습니다.)
또 차이점으로 BatchStatus는 Enum 타입이지만, ExitStatus는 생성자로 String 객체인 ExitCode를 받아 초기화 되기 때문에 사용자가 커스텀하여 사용하기에 유리하다는 점이 있습니다.
이런 status 들은 메타 테이블에 저장되어 실행했던 Job 과 Step들에 대한 정보를 제공하는 역할을 합니다.
BatchStatus 가 STATUS 컬럼에 매칭되고 ExitStatus는 EXIT_CODE 컬럼에 매칭됩니다.
BATCH_JOB_EXECUTION 테이블
BATCH_STEP_EXECUTION 테이블
일반적인 상황에서 ExitStatus는 BatchStatus와 동일하지만, 개발자에 의해 변경이 가능합니다.
또한 개발자는 ExitStatus에 따라 다음 Step으로 어떤 Step을 실행할지, 또는 Job을 종료할 지 등의 설정을 할 수 있습니다.
public Job stepNextConditionalJob() {
return jobBuilderFactory.get("stepNextConditionalJob")
.start(conditionalJobStep1())
.on("FAILED") // FAILED 일 경우
.to(conditionalJobStep3()) // step3으로 이동한다.
.on("*") // step3의 결과 관계 없이
.end() // step3으로 이동하면 Flow가 종료한다.
.from(conditionalJobStep1()) // step1로부터
.on("*") // FAILED 외에 모든 경우
.to(conditionalJobStep2()) // step2로 이동한다.
.next(conditionalJobStep3()) // step2가 정상 종료되면 step3으로 이동한다.
.on("*") // step3의 결과 관계 없이
.end() // step3으로 이동하면 Flow가 종료한다.
.end() // Job 종료
.build();
}
다음과 같이 .on() 에서 매칭될 ExitCode를 파라미터로 넘겨 분기문처럼 사용할 수 있고,
end(), fail(), stop() 을 호출하여 Job을 어떻게 종료할 지 정할 수 있습니다.
이런 처리를 스프링 배치에서는 transition
이라고 부릅니다.
이처럼, Job을 종료하는 방식이 순차적인 Step의 흐름에 의해 종료되는 것이 아니라, 사용자 정의로 Job을 끝내도록 하는 경우 end(), fail(), stop() 총 3가지 transition element
가 제공됩니다.
end: Job이 다시 restart될 수 없도록 Job의 BatchStatus를 COMPLETED
상태로 종료되도록 한다.
(end()에 파라미터로 status를 넣을 수 있는데 실제 메타 테이블에 반영될 때 보니까 BatchStatus가 아니라 ExitCode 입니다.)
fail: Job을 FAILED
상태로 중지한다. 또한 end() 와 달리 Job의 재시작을 막지 않는다. (실패한 step부터 재시작 한다.)
stop: Job을 STOPPED
상태로 중지한다. fail()과 달리 무조건 restart step을 필수로 지정해야 한다.
따라서, Job을 실행할 때 JobInstance에 대한 JobExecution이 이미 존재 하고, 그 상태가 FAILED
이거나 STOPPED
라면 설정한 브레이크 포인트부터 Job을 다시 시작한다고 생각하면 될 것 같습니다.
참고로, 다음 코드 처럼 transition
이 없을 때 Job의 status는 다음과 같습니다.
@Bean
public Job job() {
return this.jobBuilderFactory.get("job")
.start(step1())
.build();
}
FAILED
라면 Job의 BatchStatus와 ExitStatus는 모두 FILAED
이다.COMPLETED
라면 Job의 BatchStatus와 ExitStatus는 모두 COMPLETED
이다.레퍼런스
https://docs.spring.io/spring-batch/docs/current/reference/html/index-single.html#spring-batch-intro
http://hwannnn.blogspot.com/2018/06/step-flow.html