Spring Batch Job의 구성

2023-10-26 18:01:33

#spring#Batch

Spring Batch Job

  • 하나의 논리적인 배치작업을 의미합니다.
  • 배치작업을 어떻게 구성하고, 실행할것인지 명세해놓은 객체입니다.
  • 배치 작업을 구성하기 위한 최상위 인터페이스이며, Spring Batch가 기본 구현체를 제공합니다.
  • 여러 Step으로 구성될 수 있으며, 반드시 하나 이상의 Step으로 구성해야 합니다. ( Job - Step의 관계는 일대다관계입니다)

Job의 구현체

  • Spring Batch에서 제공하는 Job의 구현체는 2가지 종류가 있습니다.
  1. Simple Job : 순차적으로 Step을 실행시키는 Job을 의미합니다.
  2. Flow Job : 조건별로 분기를 따라 Step을 구성하여 실행시키는 Job을 의미합니다.

Job 구성방법

  • Spring Batch에서는 Job과 Step을 Spring Bean으로 관리한다. 때문에 @Configuration 설정 클래스에서 Job 객체를 등록해줄 수 있습니다.
@Bean
public Job helloJob() { // 1. Job 구성 
    return jobBuilderFactory.get("helloJob")
            .start(helloStep1())
            .next(helloStep2())
            .build();
}
@Bean
public Step helloStep1() {// 2. Step 구성 
    return stepBuilderFactory.get("helloStep1")
            .tasklet(((contribution, chunkContext) -> {
                System.out.println("##### step1");
                return RepeatStatus.FINISHED;
            }))
            .build();
}
@Bean
public Step helloStep2() {
    return stepBuilderFactory.get("helloStep2")
            .tasklet(((contribution, chunkContext) -> {
                System.out.println("###### step2");
                return RepeatStatus.FINISHED;
            }))
            .build();
}

Job Launcher 와 Job Parameter

  • JobLaunder 배치 작업을 실행하는 역할을 합니다.
  • JobParameter와 Job을 인자로 받아서 실행합니다.
  • 예시코드
@Component
public class JobRunner implements ApplicationRunner {

    private final Job job;
    private final JobLauncher jobLauncher;

    public JobRunner(Job job, JobLauncher jobLauncher) {
        this.job = job;
        this.jobLauncher = jobLauncher;
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        JobParameters jobParameters = new JobParametersBuilder() // 1. Job Parameter를 생성합니다.
                .addString("name", "user1")
                .toJobParameters();

        jobLauncher.run(job,jobParameters); // 2. Job Launcher가 주어진 Job과 Job Parameter를 받아서 Job을 실행합니다.
    
    }
}

Job Instance

  • Job이 실행될떄 생성되는 Job의 논리적 실행 단위 객체. 즉 작업 실행을 의미한다.
  • Job과 JobInstance는 왜 구분해야 할까?
    • Job의 설정과 구성은 동일하지만 Job이 실행되는 시점에 처리하는 내용은 다르기 때문에 Job의 실행을 구분해야 합니다.
    • JobInstance는 Job과 JobParameter의 조합으로 생성하며, 처음 시작하는 Job과 Job Parameter의 경우는 새로운 Job Instance를 생성합니다.
    • 하나의 Job은 여러번 실행될 수 있으므로 Job과 JobInstance의 연관관계는 1:N의 관계입니다.
  • BATCH_JOB_INSTANCE 테이블에 매핑됩니다.
  • JobInstance의 경우 동일한 Job과 Job Parameter의 조합인 경우 예외(JobInstanceAlreadyCompleteException)를 던집니다.즉 동일한 Job을 동일한 Job Parameter로 돌리면 중복 JobInstance로 판정됩니다.
Caused by: org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException: A job instance already exists and is complete for parameters={name=user1}.  If you want to run this job again, change the parameters.
	at org.springframework.batch.core.repository.support.SimpleJobRepository.createJobExecution(SimpleJobRepository.java:139) ~[spring-batch-core-4.3.9.jar:4.3.9]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]

Job Parameter

  • 말그대로 Job을 실행할 때 함께 포함되어 사용되는 parameter 가진 도메인 객체입니다
  • 하나의 Job안에 존재하는 여러 JobInstance를 구분하기 위한 용도이다. 즉 JobInstance와 JobParameter는 1:1 관계입니다. (테이블 관계에서는 1:N)
  • BATCH_JOB_EXECUTION_PARAM 테이블과 매핑됩니다.
  • Spring Batch에서는 STRING, DATE, LONG, DOUBLE 타입을 지원을 하며, BATCH_JOB_EXECUTION_PARAM 테이블에서 타입별로 칼럼을 가지고 있습니다.

Job Parameter 생성방식

  1. Application 생성 시점에 외부 환경변수로 주입되는 방법

빌드한 Jar파일에 다음과 같이 외부 매개변수로 KEY-VALUE 형태로 값을 주입해줄 수 있다. 이떄 문자형이 아닌 경우는 별도로 (타입명)을 지정해주어야 합니다. 혹은 program argument로 key=value형태로 넣어줄 수 있습니다.

java -jar spring-batch-0.0.1-SNAPSHOT.jar name=cs seq\(long\)=2L date\(date\)=2023/10/27 age\(double\)=3 
  1. Application Code에서 직접 생성하는 방법
JobParameters parameters = new JobParametersBuilder()
        .addString("name", "chansoo")
        .addLong("seq", 1l)
        .addDate("date", new Date())
        .addDouble("age", 16.5)
        .toJobParameters();
  • 값을 주지 않으면 DATE_VAL의 경우는 기본값으로 1970-01-01 09:00:00, STRING_VAL의 경우 빈 문자열 , LONG & DOUBLE_VAL의 경우는 0이 들어갑니다.
  1. SpEL 문법을 통해 생성하는 방법

Job Parameter를 꺼내오는 법

  1. Tasklet Based Step
  • tasklet의 경우는 StepContribution, ChunkContext 클래스에서 모두 JobParameter를 꺼내올 수 있습니다.
  • 차이점은 StepContribution은 JobParameters 타입의 객체를 반환하고, ChunkContext의 경우 Map 타입의 객체를 반환하는 차이점이 있습니다.
@Bean
public Step step1() {
    return stepBuilderFactory.get("step1")
                             .tasklet((contribution, chunkContext) -> {
                                 JobParameters params = contribution.getStepExecution().getJobExecution()
                                                                           .getJobParameters();
                                 String name = params.getString("name");
                                 Long seq = params.getLong("seq");
                                 Date date = params.getDate("date");
                                 Double age = params.getDouble("age");

                                 Map<String, Object> jobParameters = chunkContext.getStepContext()
                                                                                 .getJobParameters();
                                 return RepeatStatus.FINISHED;
                             })
                             .build();
}

Job Execution

  • Job Instance에 대한 한번의 시도를 의미하는 객체로서 Job 실행 중에 발생한 정보들을 저장하고 있는 객체입니다
  • 즉 Job Instance와 Job Execution은 1:N의 관계입니다. (한번의 Job Instance가 여러번 실행될 수 있음으로)
  • 작업 시작시간, 작업 종료시간, 작업의 실행 결과 상태값(시작/완료/실패/종료)속성을 가집니다.
    • Job Execution 의 상태 결과가 COMPLETED 라면 Job Instance의 실행이 완료된것으로 간주하여 재실행이 불가능합니다. (JobInstanceAlreadyCompleteException예외가 던져집니다.)
    • Job Execution 의 상태 결과가 FAILED 라면 COMPLETED가 될떄까지 하나의 Job Instance를 여러번 재실행할 수 있습니다. (동일한 Job parameter라도 재시작이 가능합니다, 재실행될떄마다 BATCH_JOB_EXECUTION_PARAMS 테이블에 Job parameter 정보가 누적됩니다)
  • BATCH_JOB_EXECUTION 테이블과 매핑됩니다.

Reference

프로필 이미지
@chani
바둑 좋아하는 개발자의 의미있는 학습 기록을 위한 공간입니다.

댓글

이 게시글에 대한 의견을 공유해주세요!

댓글