[SpringBatch 실습] 13. incrementer 설정하기, JobParametersIncrementer 를 구현하여 커스텀 설정하기

반응형
728x90
반응형

incrementer() 사용 이유를 알아보자.

Job 생성
package com.project.springbatch._20_incrementer;

import lombok.RequiredArgsConstructor;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/*
--job.name=incrementerJob
 */

/**
 * JobParametersIncrementer.java - getNext()
 */
@Configuration
@RequiredArgsConstructor
public class IncrementerConfiguration {

    // job 생성
    private final JobBuilderFactory jobBuilderFactory;
    private final StepBuilderFactory stepBuilderFactory;

    @Bean
    public Job incrementerJob() {
        return this.jobBuilderFactory.get("incrementerJob")
                /* step start */
                .start(incrementerStep1())
                .next(incrementerStep2())
                .build();
    }

    @Bean
    public Step incrementerStep1() {
        return stepBuilderFactory.get("incrementerStep1")
                .tasklet(new Tasklet() {
                    @Override
                    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
                        System.out.println("incrementerStep1");
                        return RepeatStatus.FINISHED;
                    }
                })
                .build();
    }

    @Bean
    public Step incrementerStep2() {
        return stepBuilderFactory.get("incrementerStep2")
                .tasklet(new Tasklet() {
                    @Override
                    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
                        System.out.println("incrementerStep2");
                        return RepeatStatus.FINISHED;
                    }
                })
                .build();
    }
}

 

 

 

첫번째 수행

incrementerStep1
incrementerStep2

 

 

DB 테이블 조회

1) BATCH_JOB_EXECUTION

COLUMN VALUE
STATUS COMPLETED
EXIT_CODE COMPLETED
JOB_EXECUTION_ID 9

 

2) BATCH_JOB_INSTANCE

COLUMN VALUE
JOB_NAME incrementerJob

 

3) BATCH_STEP_EXECUTION

  • incrementerStep1
COLUMN VALUE
STEP_NAME incrementerStep1
EXIT_CODE COMPLETED
STATUS COMPLETED
JOB_EXECUTION_ID 9

 

  • incrementerStep2
COLUMN VALUE
STEP_NAME incrementerStep2
EXIT_CODE COMPLETED
STATUS COMPLETED
JOB_EXECUTION_ID 9

 

 

두번째 수행

Step already complete or not restartable, so no action to execute: StepExecution:

이미 COMPLETED로 STEP이 모두 완료됬기 때문에 위와 같은 로그가 출력되면서 수행되지 않는다.

동일한 JOB을 수행시키기 위해서는 첫번째 실행 때와 다른 파라미터 값이 필요하다.

 

 

 

Job 수정

package com.project.springbatch._20_incrementer;

import lombok.RequiredArgsConstructor;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/*
--job.name=incrementerJob
 */

/**
 * JobParametersIncrementer.java - getNext()
 */
@Configuration
@RequiredArgsConstructor
public class IncrementerConfiguration {

    // job 생성
    private final JobBuilderFactory jobBuilderFactory;
    private final StepBuilderFactory stepBuilderFactory;

    @Bean
    public Job incrementerJob() {
        return this.jobBuilderFactory.get("incrementerJob")
                /* step start */
                .start(incrementerStep1())
                .next(incrementerStep2())
                // 기존 구현체
                .incrementer(new RunIdIncrementer())
                .build();
    }

    @Bean
    public Step incrementerStep1() {
        return stepBuilderFactory.get("incrementerStep1")
                .tasklet(new Tasklet() {
                    @Override
                    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
                        System.out.println("incrementerStep1");
                        return RepeatStatus.FINISHED;
                    }
                })
                .build();
    }

    @Bean
    public Step incrementerStep2() {
        return stepBuilderFactory.get("incrementerStep2")
                .tasklet(new Tasklet() {
                    @Override
                    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
                        System.out.println("incrementerStep2");
                        return RepeatStatus.FINISHED;
                    }
                })
                .build();
    }
}

1) incrementer(new RunIdIncrementer()) 추가

@Bean
public Job incrementerJob() {
    return this.jobBuilderFactory.get("incrementerJob")
            /* step start */
            .start(incrementerStep1())
            .next(incrementerStep2())
            // 기존 구현체
            .incrementer(new RunIdIncrementer())
            .build();
}

 

 

첫번째 실행

incrementerStep1
incrementerStep2

 

 

DB 테이블 조회

1) BATCH_JOB_EXECUTION

COLUMN VALUE
STATUS COMPLETED
EXIT_CODE COMPLETED
JOB_EXECUTION_ID 11

 

2) BATCH_JOB_INSTANCE

COLUMN VALUE
JOB_NAME incrementerJob
JON_INSTANCE_ID 9

 

3) BATCH_STEP_EXECUTION

  • incrementerStep1
COLUMN VALUE
STEP_NAME incrementerStep1
EXIT_CODE COMPLETED
STATUS COMPLETED
JOB_EXECUTION_ID 11

 

  • incrementerStep2
COLUMN VALUE
STEP_NAME incrementerStep2
EXIT_CODE COMPLETED
STATUS COMPLETED
JOB_EXECUTION_ID 11

 

4) BATCH_JOB_EXECUTION_PARAMS

COLUMN VALUE
long_val 1
type_cd LONG
key_name run.id
JOB_EXECUTION_ID 11

 

 

 

두번째 실행

incrementerStep1
incrementerStep2

두번째 실행일때, 아까와 달리 정상적으로 Job이 수행된다.

 

 

 

DB 테이블 조회

1) BATCH_JOB_EXECUTION

COLUMN VALUE
STATUS COMPLETED
EXIT_CODE COMPLETED
JOB_EXECUTION_ID 12

 

2) BATCH_JOB_INSTANCE

COLUMN VALUE
JOB_NAME incrementerJob
JON_INSTANCE_ID 10

 

3) BATCH_STEP_EXECUTION

  • incrementerStep1
COLUMN VALUE
STEP_NAME incrementerStep1
EXIT_CODE COMPLETED
STATUS COMPLETED
JOB_EXECUTION_ID 12

 

  • incrementerStep2
COLUMN VALUE
STEP_NAME incrementerStep2
EXIT_CODE COMPLETED
STATUS COMPLETED
JOB_EXECUTION_ID 12

 

4) BATCH_JOB_EXECUTION_PARAMS

COLUMN VALUE
long_val 2
type_cd LONG
key_name run.id
JOB_EXECUTION_ID 12

 

 

BATCH_JOB_EXECUTION_PARAMS 테이블 비교

  key_name long_val
첫번째 수행 run.id 1
두번째 수행 run.id 2

 

incrementer(new RunIdIncrementer())를 추가해줌으로써 Job 수행시 파라미터 run.id가 추가되고 동일한 Job을 수행할때마다 1씩 증가됨을 알 수 있다.

 

 

 

Incrementer 커스텀

CustomJobParametersIncrementer.java
package com.project.springbatch._20_incrementer;

import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.JobParametersIncrementer;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * incrementer 구현
 */
public class CustomJobParametersIncrementer implements JobParametersIncrementer {
    static final SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd-hhmmss");

    /**
     * Date 를 incrementer 로 지정해보자.
     * @param jobParameters
     * @return
     */
    @Override
    public JobParameters getNext(JobParameters jobParameters) {
        String id = format.format(new Date());

        return new JobParametersBuilder().addString("run.id", id).toJobParameters();
    }
}

 

Job 수정
@Bean
    public Job incrementerJob() {
        return this.jobBuilderFactory.get("incrementerJob")
                /* step start */
                .start(incrementerStep1())
                .next(incrementerStep2())
                .incrementer(new CustomJobParametersIncrementer())
                .build();
    }

 

 

BATCH_JOB_EXECUTION_PARAMS 테이블 비교

  key_name VALUE
첫번째 수행 run.id 20220530-093219
두번째 수행 run.id 20220530-093229

 

CustomJobParametersIncrementer.java의 getNext() 메서드에서 구현한대로 수행 일시를 id로 저장하고있다.

 

 

 

 

반응형

Designed by JB FACTORY