본문 바로가기
Practice/SpringBatch

Day 2. SpringBatch Job 메타 테이블이란?

반응형

Spring-Batch의 기본 개념을 정리하고, 간단한 실습 환경부터 연습해보는 포스팅입니다

참고

Spring-Batch 공식문서(4.3.3 기준)

https://docs.spring.io/spring-batch/docs/4.3.3/reference/html/

 

Spring Batch - Reference Documentation

Welcome to the Spring Batch reference documentation! This documentation is also available as single html and pdf documents. The reference documentation is divided into several sections: The following appendices are available: Lucas Ward, Dave Syer, Thomas

docs.spring.io

 

 

이동욱님의 블로그

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

 

1. Spring Batch 가이드 - 배치 어플리케이션이란?

Spring Batch In Action이 2011년 이후 개정판이 나오지도 않고 (2019.03 기준), 한글 번역판도 없고, 국내 Spring Batch 글 대부분이 튜토리얼이거나 공식 문서 중 일부분을 짧게 번역한 내용들이라 대용량 시

jojoldu.tistory.com


1. 메타 테이블 ERD 

 

2. Job 메타 테이블 소개

2-1. BATCH_JOB_INSTANCE

  • 속성
    컬럼명 설명
    JOB_INSTANCE_ID BATCH_JOB_INSTANCE 테이블의 PK
    VERSION 해당 레코드가 update 될때마다 1씩 증가합니다
    JOB_NAME 생성한(실행한) Job 이름
    JOB_KEY 동일한 Job이름의 JobInstance는 Job의 실행시점에 부여되는 고유한 JobParameter의 값을 통해 식별됩니다
    그리고 이렇게 식별되는 값의 직렬화(serialization)된 결과를 JOB_KEY라는 값으로 기록됩니다
  • BATCH_JOB_INSTANCE는 JobParameter에 따라 생성되는 테이블입니다
  • JobParameter란?
    • SpringBatch가 실행될 때 외부로 부터 주입받는 값
    • 같은 Job이여도 JobParameter가 다르면 BATCH_JOB_INSTACNE 테이블에 레코드가 추가되고, 다르다면 추가되지 않습니다
  • 예제: JobParameter로 requestDate를 입력받아 로그로 출력하는 Job 생성
    // Example JobParameters
    @Slf4j
    @RequiredArgsConstructor
    @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을 생성하고 Step을 등록할때 simepleStep1에 null을 파라미터로 입력 ( @Value 어노테이션으로 매핑되기 때문에 null을 입력해도 됩니다 )
    • simpleStep1에 @JobScope 어노테이션 추가
    • simpleStep1의 파라미터로 @Value("#{jobParameters[requestDate]}") String requestDate 추가
    • Program Arguments에 requestDate=20210904라는 값을 넣고 실행시키면 정상 실행되고 아래 처럼 레코드가 추가된 것을 확인 할 수 있습니다
    • 여기서 다시 한 번 실행시키면? 위에서 설명한 것 처럼 같은 JobParameters로는 레코드 추가가 안되고 정상적으로 실행조차 안되는 것을 확인할 수 있습니다
      Caused by: org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException: A job instance already exists and is complete for parameters={requestDate=20210904}.  If you want to run this job again, change the parameters.​
  • 결론: 동일한 Job이 Job Parameter가 달라지면 그때마다 BATCH_JOB_INSTANCE에 생성되며, 동일한 Job Parameter는 여러개 존재할 수 없습니다 

 

2-2. BATCH_JOB_EXECUTION

  • BATCH_JOB_INSTANCE 테이블이 Job의 실행단위를 구분짓는 것이라면 BATCH_JOB_EXECUTION 테이블은 그 실행단위에 대한 실행횟수(1번 또는 1번이상)를 나타내는JobExecute에 관한 정보를 담고 있습니다
  • 속성
    속성 설명
    JOB_EXECUTION_ID JobInstance에 대한 실행횟수(JobExecution)를 고유하게 식별될할 수 있는 기본 키입니다.
    VERSION 해당 레코드가 update 될때마다 1씩 증가합니다
    JOB_INSTANCE_ID 실행된 JOB_INSTANCE_ID(BATCH_JOB_INSTANCE table)
    CREATE_TIME 실행(Execution)이 생성된 시점을 TimeStamp 형식으로 기록합니다
    START_TIME 실행(Execution)이 시작된 시점을 TimeStamp 형식으로 기록합니다
    END_TIME 실행이 종료된 시점을 TimeStamp으로 기록합니다
    성공 또는 실패와 상관없이 순수히 끝난 시점을 의미
    STATUS 실행의 상태를 COMPLETED, STARTED, FAILED 와 같은 미리 정의된 Enum 값으로 기록
    org.springframework.batch.core.BatchStatus 
    EXIT_CODE 실행 종료코드를 COMPLETED, NOOP, FAILED 와 같은 Enum 값으로 기록
    org.springframework.batch.core.ExitStatus
    EXIT_MESSAGE 정상적으로 종료되지 않았을 경우에 대한 상세 메시지
    LAST_UPDATED 실행(Execution)이 마지막으로 영속(persisted)에 놓인 시점을 TimeStamp 형식으로 기록
    JOB_CONFIGURATION_LOCATION ...?
    • STATUS vs EXIT_CODE
      • STATUS는 배치의 실행 상태 그대로를 나타내고 EXIT_CODE는 배치가 종료될 때의 상태 값을 나타냅니다
      • 만약 어떤 STEP도 정의되어있지 않다면 STATUS는 COMPLETE이지만 EXIT_CODE는 NOOP가 됩니다
  • JOB_EXECUTION와 JOB_INSTANCE는 부모-자식 관계
  • 즉 JOB_EXECUTION table은 자신의 부모 JOB_INSTACNE가 성공/실패했던 모든 내역을 갖고 있습니다
    • 단 같은 JobParameters에 대해 새로운 JOB_INSTANCE가 생기지 않았을 경우, JOB_EXECUTION 역시 기록되지 않습니다
  • 예제: 같은 Job안에 두번째 Step을 추가
    // Add Step2 
    @Slf4j
    @RequiredArgsConstructor
    @Configuration
    public class SimpleJobConfiguration {
    
        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();
        }
    
    }
    • simpleJob에 next 메서드를 이용해 simpleStep2를 추가했습니다
    • 기존의 simpleStep1에서는 runtimeException을 던지게 변경
    • Program Arguments를 requestDate=20210904에서 requestDate=20210905로 변경
      • 변경하지 않으면 위에서 발생했던 JobInstanceAlreadyCompleteException 예외가 나오게 됩니다
    • 실행 결과
      java.lang.IllegalArgumentException: step1에서 실패​

      • 당연히 step1에서 RuntimeException을 던졌기 때문에 해당 Exception이 발생하며 종료되었습니다
      • 같은 Job에서 다른 JobParametes가 실행되었기 때문에 BATCH_JOB_INSTANCE table에는 레코드가 추가
      • BATCH_JOB_EXECUTION table
        • JOB_EXECUTION_ID = 5 인 레코드를 보면 STATUS:FAILED, EXIT_CODE:FAILED로 기록되어 있으며 EXIT_MESSAGE가 위 로그에서 봤던 오류내용이 기록되어있는 것을 확인할 수 있습니다

      • 위의 정의된 코드중 STEP1에서 발생시키던 RuntimeException을 다시 정상적으로 수행되게 수정한 후 실행시켜 보겠습니다
      • 같은 JobParameters로 실행시켜보면 6번째 로우에서 보이는 것 처럼 같은 JOB_INSTANCE_ID를 가진 STATUS가 COMPLETED 상태의 레코드가 기록된 것을 확인 할 수 있습니다
    • 결론: Spring Batch는 동일한 Job Parameter로 성공한 기록이 있을때만 재수행이 안된다

 

2-3. JOB 개념 정리

  • Job: 하나의 실행 단위 ( "simpleJob" )
  • JobInstance: JobParameters 단위로 생성되는 Job ( "requestDate=20210904 로 실행된 simpleJob" )
  • JobExecute: 생성된 JobInstance의 작업 시도 내역 ( "requestDate=20210904 로 실행된 simpleJob의 1번째, N번째 시도" )

 

2-4. BATCH_JOB_EXECUTION_PARAMS

  • 입력받은 JobParameters에 대한 모든 기록이 담겨있는 테이블
  • 속성
    속성 설명
    JOB_EXECUTION_ID BATCH_JOB_EXECUTION 테이블의 PK입니다 ( 외래 키 )
    TYPE_CD JobParameters의 타입 유형, null 값이 올 수 없음
    KEY_NAME 매개 변수의 키 ( program argument로 입력한 키 )
    STRING_VAL 유형이 문자열인 경우 매개변수 값입니다
    DATE_VAL 유형이 날짜인 경우 매개변수 값입니다
    LONG_VAL 유형이 긴 경우 매개변수 값입니다
    DOUBLE_VAL 유형이 이중인 경우 매개변수 값입니다
    IDENTIFYING 같은 JobParameters를 구분할 수 있는지 Flag인거 같은데... 추후 더 알아보겟습니다

 

2-5. BATCH_JOB_EXECUTION_CONTEXT

  • 작업의 ExecutionContext와 관련된 모든 정보를 기록합니다
  • 1개의 JobExecution에 각 JobExecutionContext가 있으며 특정 작업 실행에 필요한 모든 작업 레벨 데이터를 포함합니다
  • 이 데이터는 일반적으로 JobInstance"중단된 위치에서 시작"할 수 있도록 실패 후 검색해야 하는 상태를 나타냅니다
  • 속성
    속성 설명
    JOB_EXECUTION_ID BATCH_JOB_EXECUTION의 PK입니다 ( 외래 키 )
    SHORT_CONTEXT SERIALIZED_CONTEXT의 버전을 나타내는 문자열
    SERIALIZED_CONTEXT 직렬화(serialized)된 전체 컨테스트
728x90
반응형

'Practice > SpringBatch' 카테고리의 다른 글

Day 5. Spring Batch Chunk  (0) 2021.10.07
Day 4. Spring Batch Scope  (0) 2021.09.09
Day 3. Spring Batch Job 흐름 정의  (0) 2021.09.05
Day 1. Spring-Batch 환경 설정  (0) 2021.09.01