[spring-batch] BatchSatus, ExitStatus

Minsu Kang·2021년 4월 24일

BatchStatus와 ExitStatus에 대한 정의

스프링 배치에서는 현재 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 테이블

Transition

일반적인 상황에서 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();
}
  • 마지막 Step의 ExitStatus가 FAILED 라면 Job의 BatchStatus와 ExitStatus는 모두 FILAED 이다.
  • 마지막 Step의 ExitStatus가 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

0개의 댓글