본문 바로가기
Spring Batch

Spring Batch 개발기 ( 4. MetaData테이블 )

by SICDev 2021. 7. 16.
반응형

메타 데이터 테이블은 무엇이 있는지🤔 어떤 역할을 하는지 간단하게만 알아보자❗❗

 


1. BATCH_JOB_INSTANCE

 

BATCH_JOB_INSTANCE 테이블 데이터를 보면 이전에 실행했던 Batch에 대한 기록이 저장되어있다❗

 

BATCH_JOB_INSTANCE에는 Job Parameter에 따라 데이터가 기록된다❗

 

Job Parameter가 무엇이냐면 Batch를 실행시킬때 내부/외부에서 받아올 수 있는 파라미터이다.

웹 개발을 할때 메서드에 파라미터 값을 받지 않는가??? 그거와 똑같다고 생각하면된다❗

 

그럼 이 Job Parameter로 무엇을 하나???🤔

Job Parameter로 받은 값을 가공하여 사용할 수 있다😊

 

그리고 Job Parameter값에 따라 BATCH_JOB_INSTANCE에 데이터가 기록된다고 했는데, 무슨 의미냐면

같은 Job Parameter로 같은 Batch를 실행 시키면 Exception이 뜨면서 BATCH_JOB_INSTANCE에 기록되지 않고,

다른 Job Parameter로 실행시키면 BATCH_JOB_INSTANCE에 기록된다👍👍


확인을 한 번 해보자❗

기존에 작성했던 BatchConfig.java 를 수정하자

 

package com.example.batchtest.job;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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.JobScope;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Slf4j
@RequiredArgsConstructor
@Configuration
public class BatchConfig {
    private final JobBuilderFactory jobBuilderFactory;
    private final StepBuilderFactory stepBuilderFactory;

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

    @Bean
    @JobScope
    public Step testStep(@Value("#{jobParameters[testParameter]}") String testParameter ) {
        return stepBuilderFactory.get("testStep")
                .tasklet((contribution, chunkContext) -> {
                    log.info("=====================testStep 실행===============");
                    log.info("=====================testParameter : "+testParameter+"===============");
                    return RepeatStatus.FINISHED;
                })
                .build();
    }
}

 

IDE 실행환경 탭을 클릭해서 들어가자

 

Environment 탭 아래 Program arguments 칸안에 파라미터값을 적어주자

 

저장하고 Batch를 실행시켜보면❗

아주 잘 실행이 되었다.

DB에도 아주 잘 들어가져있다👍

 

같은 Batch Parameter로 Batch를 실행시키면 Exception이 뜨면서 BATCH_JOB_INSTANCE에도 기록이 안된다 했으니 같은 파라미터로 한번 더 실행시켜보자❗

A job instance already exists and is complete for parameters={testParameter=test1}.  If you want to run this job again, change the parameters. 라는 문구와 함께 Exception이 발생한다.

 

DB를 확인해봐도 기록되지 않았다❗

 


2. BATCH_JOB_EXECUTION

BATCH_JOB_EXECUTION에도 2개의 데이터가 기록되어있다❗

처음에 파라미터 없이 실행시켰던 배치testParameter=test1 로 실행시켰던 배치

 

JOB_EXECUTION과 JOB_INSTANCE는 부모-자식과 같은 관계를 가지고있다.

JOB_EXECUTION은 JOB_INSTANCE의 성공했던 기록과 실패했던 기록 모두를 가지고 있다❗

 

그럼 코드를 수정해서 강제로 실패를 한번 시켜보자😊

물론 파라미터값은 다른값으로 변경해주어야 한다❗❗❗  나는 testParameter=test2 이렇게 파라미터를 주었다😉

package com.example.batchtest.job;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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.JobScope;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Slf4j
@RequiredArgsConstructor
@Configuration
public class BatchConfig {
    private final JobBuilderFactory jobBuilderFactory;
    private final StepBuilderFactory stepBuilderFactory;

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

    @Bean
    @JobScope
    public Step testStep(@Value("#{jobParameters[testParameter]}") String testParameter ) {
        return stepBuilderFactory.get("testStep")
                .tasklet((contribution, chunkContext) -> {
                    throw new IllegalArgumentException("================== 실패 ===============");
                })
                .build();
    }
}

 

 

이렇게 Exception이 터지면서 배치가 실패했다❗ 

 

BATCH_JOB_EXECUTION 테이블을 보면 FAILED라고 데이터가 기록된것을 확인해 볼 수 있다.

 

그럼 다시 코드를 수정해서 성공시켜보자❗

이번엔 파라미터값은 똑같이 testParameter=test2 이렇게 줘서 실행시켜보자

이전에 이전에 실행했던 파라미터값으로 같은 배치를 실행시키면 Exception이 터진다고 했다😒 그런지 다시 확인해보자❗

 

package com.example.batchtest.job;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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.JobScope;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Slf4j
@RequiredArgsConstructor
@Configuration
public class BatchConfig {
    private final JobBuilderFactory jobBuilderFactory;
    private final StepBuilderFactory stepBuilderFactory;

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

    @Bean
    @JobScope
    public Step testStep(@Value("#{jobParameters[testParameter]}") String testParameter ) {
        return stepBuilderFactory.get("testStep")
                .tasklet((contribution, chunkContext) -> {
                    log.info("=====================testStep 실행===============");
                    log.info("=====================testParameter : "+testParameter+"===============");
                    return RepeatStatus.FINISHED;
                })
                .build();
    }
}

 

또잉.....👀 실행이 되었다...❓

 

분명히 같은 Job Parameter로 같은 Batch Job을 실행시키면 에러가 발생해야하는데...발생하지 않았다❗

 

DB를 살펴보면 우리가 testPrameter=test2로 실행시켰던 JOB_INSTANCE가 2개가 존재한다❗

첫번째는 실패(FAILED)했던 기록, 두번째는 성공(COMPLITED)했던 기록이다.

 

Spring Batch에서 동일한 Job Parameter로 기존에 성공한 기록이 있을때 다시 실행을 못한다❗

 


3. BATCH_JOB_EXECUTION_PARAMS

 

BATCH_JOB_EXECUTION_PARMAS 테이블을 살펴보자❗

이름에서도 알 수 있듯이 Batch Job을 실행시킬때 우리가 Job Parameter로 입력했던 값들을 기록해 놓은 테이블이다.

 

DB를 살펴보면 우리가 지금까지 입력했던 모든 파라미터값들이 들어가져있다.

 

 


4. BATCH_JOB_SEQ , BATCH_JOB_EXECUTION_SEQ

 

BATCH_JOB_SEQ 테이블도 역시 이름에서 유추해볼 수 있듯이 BATCH_JOB_INSTANCE에 기록할 때 쓰이는 시퀀스 값이다. 현재 총 몇번의 배치가 실행되었는지 알 수 있다❗

BATCH_JOB_INSTANCE 기록에 쓰이는 시퀀스 값이기 때문에 실패한 Batch는 제외해 시퀀스값이 3으로 기록 되어있다.

 

 

BATCH_JOB_EXECUTION_SEQ 테이블은 BATCH_JOB_EXECUTION 테이블에 기록할때 쓰이는 시퀀스 값이다. 

우리는 ( 성공 3번, 실패 1번 ) 총 4번의 배치를 실행시켰기 때문에 시퀀스 값은 4이다.

BATCH_JOB_EXECUTION 의 시퀀스이기 때문에 성공, 실패한 Batch의 갯수 만큼 늘어나 있을 것이다😀

 

 


5. BATCH_JOB_EXECUTION_CONTEXT

 

BATCH_JOB_EXECUTION_CONTEXT 테이블은 이름으로 봐서는 잘 모르겠다.

 

컨텍스트(context)라는건 SPRING에서도 많이 쓰이는 말인데, 간단히 말해 컨텍스트는 어떤 그것에 대한 모든 정보를 말한다.

예를 들어 피카츄의 컨텍스트라고 하면 피카츄의 모든 정보라고 간단히 생각하면된다.

 

Spring Batch에서는 tasklet 혹은 step 등이 서로 정보를 교환해야 할 때가 생기는데, 그때 BATCH_JOB_EXECUTION_CONTEXT 테이블에 있는 값을 이용해 정보를 교환 할 수 있다.

 


나머지 테이블들은 위의 테이블들과 거의 동일한 테이블들이니 찾아보면 금방 알 수 있을것이다😀

 

다음엔 진짜진짜진짜 영화진흥원에서 제공해주는 API를 이용해 BATCH를 만들어보자❗

 

 

 

 

 

출처

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