[Spring Batch] 메타 데이터

메타 테이블을 역할과 어떤 것들을 담고 있는 지 확인하려 한다.

1. BATCH_JOB_INSTANCE

정의

BATCH_JOB_INSTANCE 테이블 : Job Parameter에 따라 생성되는 테이블

  • JOB_INSTANCE_ID 
    BATCH_JOB_INSTANCE 테이블의 PK
  • JOB_NAME
    수행한 Batch Job Name

위의 사진을 보면 전글에서 실행했던 simpleJob이 저장되어 있는 것을 확인할 수 있다.
BATCH_JOB_INSTANCE 테이블Job Parameter에 따라 생성되는 테이블이다.

Job Parameter : Spring Batch가 실행될 때 외부에서 받을 수 있는 파라미터

같은 Batch Job이라도 Job Parameter다르면 BATCH_JOB_INSTANCE에는 기록되며, Job Parameter같다면 기록되지 않는다.

변경된 코드

SimpleJobConfig.java

@Slf4j // log 사용을 위한 lombok 어노테이션
@RequiredArgsConstructor // 생성자 DI를 위한 lombok 어노테이션
@Configuration
public class SimpleJobConfiguration {
    private final JobBuilderFactory jobBuilderFactory;
    private final StepBuilderFactory stepBuilderFactory;

    @Bean
    public Job simpleJob() {
        return jobBuilderFactory.get("simpleJob")
                .start(simpleStep1(null))
                .build();
    }

    @Bean
    @JobScope
    public Step simpleStep1(@Value("#{jobParameters[requestDate]}") String requestDate) {
        return stepBuilderFactory.get("simpleStep1")
                .tasklet((contribution, chunkContext) -> {
                    log.info(">>>>> This is Step1");
                    log.info(">>>>> requestDate = {}", requestDate);
                    return RepeatStatus.FINISHED;
                })
                .build();
    }
}

변경된 코드는 Job Parameter로 받은 값을 로그에 추가로 출력시키는 기능이다.

Program arguments에 requestDate=20180805 를 입력한다.

실행 결과

이제 Job Parameter를 넣어서 Batch를 실행해 본다.

실행환경 탭을 클릭해서 설정창으로 이동한다.

Program arguments에 requestDate=20180805 를 입력한다.

Job Parameter가 전달되어 로그가 잘 찍힌걸 확인할 수 있다.

Job Parameter가 다르면 Job이 실행된다고 했는데 이를 확인해보자.

Job Parameter가 다른 경우

Program arguments에 requestDate=20211122 를 입력한다.

Job Parameter가 같은 경우

오류 코드와 함께 Job이 실행되지 않는다.

2. BATCH_JOB_EXECUTION

설명

JOB_EXECUTION 테이블을 보면 4개의 ROW가 있다.
이전에 실행했던 파라미터가 없는 simpleJob, requestDate=20180805 파라미터로 실행했던 simpleJob, requestDate=20180806 파라미터로 실행했던 simpleJob 까지 이렇게 4개의 실행 데이터이다.

JOB_EXECUTIONJOB_INSTANCE는 부모-자식 관계이다.
(JOB_INSTACNE - 부모 / JOB_EXECUTION - 자식 )
JOB_EXECUTION은 자신의 부모 JOB_INSTACNE가 성공/실패했던 모든 내역을 갖고 있다.

코드 변경

SimpleJobConfig.java

@Slf4j // log 사용을 위한 lombok 어노테이션
@RequiredArgsConstructor // 생성자 DI를 위한 lombok 어노테이션
@Configuration
public class SimpleJobConfig{
    private final JobBuilderFactory jobBuilderFactory;
    private final StepBuilderFactory stepBuilderFactory;

    @Bean
    public Job simpleJob() {
        return jobBuilderFactory.get("simpleJob")
                .start(simpleStep1(null))
                .next(simpleStep2(null))
                .build();
    }

    @Bean
    @JobScope
    public Step simpleStep1(@Value("#{jobParameters[requestDate]}") String requestDate) {
        return stepBuilderFactory.get("simpleStep1")
                .tasklet((contribution, chunkContext) -> {
                    throw new IllegalArgumentException("step1에서 실패합니다.");
                })
                .build();
    }

    @Bean
    @JobScope
    public Step simpleStep2(@Value("#{jobParameters[requestDate]}") String requestDate) {
        return stepBuilderFactory.get("simpleStep2")
                .tasklet((contribution, chunkContext) -> {
                    log.info(">>>>> This is Step2");
                    log.info(">>>>> requestDate = {}", requestDate);
                    return RepeatStatus.FINISHED;
                })
                .build();
    }
}

실행 결과

이번에는 Job Parameter를 requestDate=20211122로 변경한다.


의도한 Exception과 함께 Batch Job이 실패했음을 볼 수 있다.

BATCH_JOB_EXECUTION 테이블을 살펴보면
4번째 JOB_INSTACNE를 FK로 물고 있는 EXECUTION이 FAILED 라는 것을 확인할 수 있다.

코드를 수정해서 Job을 성공시켜 보면

변경된 코드

  @Bean
    @JobScope
    public Step simpleStep1(@Value("#{jobParameters[requestDate]}") String requestDate) {
        return stepBuilderFactory.get("simpleStep1")
                .tasklet((contribution, chunkContext) -> {
                    log.info(">>>>> This is Step1");
                    log.info(">>>>> requestDate = {}", requestDate);
                    return RepeatStatus.FINISHED;
                })
                .build();
    }

변경된 코드로 다시 실행해보면 위의 사진과 같이 Job이 성공적으로 수행된 것을 확인할 수 있다.

테이블을 살펴보면 JOB_INSTANCE와 BATCH_JOB_EXECUTION의 차이를 확인할 수 있다.

BATCH_JOB_EXECUTION의 JOB_INSTANCE_ID 컬럼을 보면 같은 ID (4) 를 가진 2개의 ROW가 보인다.
그 중 첫번째 ROW는 STATUS 가 FAILED 이지만, 2번째 ROW는 COMPLETED 이다.

Job Parameter requestDate=20211123로 생성된 BATCH_JOB_INSTACNE (id=4) 가 2번 실행되었고, 첫번째는 실패, 두번째는 성공했다는 것을 알 수 있다.

동일한 Job Parameter로 2번 실행했는데 같은 파라미터로 실행되었다는 에러가 발생하지 않는다.
Spring Batch는 동일한 Job Parameter로 성공한 기록이 있을때만 재수행이 안된다는 것을 알 수 있다.

3. JOB, JOB_INSTANCE, JOB_EXECUTION

여기서 말하는 Job이란 위에 작성한 Spring Batch Job을 말한다.

위 2개의 테이블 외에도 더 많은 Job관련 테이블이 존재한다.

  • BATCH_JOB_EXECUTION_PARAM
    BATCH_JOB_EXECUTION 테이블이 생성될 당시에 입력 받은 Job Parameter를 담고 있다.

Reference

https://jojoldu.tistory.com/326?category=902551

좋은 웹페이지 즐겨찾기