[SpringBatch 실습] 19. EXIT_CODE를 직접 만들어서 적용해보기

반응형
728x90
반응형

Job 생성

CustomExitStatusConfiguration.java
import lombok.RequiredArgsConstructor;
import org.springframework.batch.core.ExitStatus;
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=customExitStatusJob
 */

@Configuration
@RequiredArgsConstructor
public class CustomExitStatusConfiguration {

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

    @Bean
    public Job customExitStatusJob() {
        return this.jobBuilderFactory.get("customExitStatusJob")
                .start(customExitStatusStep1())
                    .on("FAILED")
                    .to(customExitStatusStep2())
                    .on("PASS") // 사용자 코드
                    .stop()
                .end()
                .build();
    }

    @Bean
    public Step customExitStatusStep1() {
        return stepBuilderFactory.get("customExitStatusStep1")
                .tasklet(new Tasklet() {
                    @Override
                    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
                        System.out.println("customExitStatusStep1");
                        // FAILED 설정
                        contribution.getStepExecution().setExitStatus(ExitStatus.FAILED);
                        return RepeatStatus.FINISHED;
                    }
                })
                .build();
    }

    @Bean
    public Step customExitStatusStep2() {
        return stepBuilderFactory.get("customExitStatusStep2")
                // 빈으로 등록해도되고, 이렇게 객체 생성해도 된다.
                .tasklet(new CustomTasklet())
//                .listener(new PassCheckingListener())
                .build();
    }
}

1) customExitStatusJob()

.start(customExitStatusStep1())
    .on("FAILED")
    .to(customExitStatusStep2())
    .on("PASS") // 사용자 코드
    .stop()

customExitStatusSTep1()이 "FAILED"이면 customExitStatusStep2()를 실행시키고, customExitStatusStep2()가 "PASS"이면 해당 Job을 "STOPPED" 상태로 종료시킨다.

 

 

CustomTasklet.java
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;

public class CustomTasklet implements Tasklet {
    /**
     * 비즈니스 로직 구현
     * @param stepContribution
     * @param chunkContext
     * @return
     * @throws Exception
     */
    @Override
    public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
        System.out.println("taskletTestStep2");
        return RepeatStatus.FINISHED;
    }
}

 

 

 

배치 실행 결과

customExitStatusStep1
taskletTestStep2

 

결과를 보면 Job의 STATUS와 EXIT_CODE 가 모두 "FAILED"이다.

 

customExitStatusJob()
@Bean
    public Job customExitStatusJob() {
        return this.jobBuilderFactory.get("customExitStatusJob")
                .start(customExitStatusStep1())
                    .on("FAILED")
                    .to(customExitStatusStep2())
                    .on("PASS") // 사용자 코드
                    .stop()
                .end()
                .build();
    }

 

customExitStatusStep2() 수행 후, .on("PASS")를 만족하지 못했기 때문에 Job이 FAILED 상태로 종료된다.

 

 

 

DB 테이블 조회

1) BATCH_JOB_EXECUTION

COLUMN VALUE
STATUS FAILED
EXIT_CODE FAILED
JOB_EXECUTION_ID 19

 

2) BATCH_JOB_INSTANCE

COLUMN VALUE
JOB_NAME customExitStatusJob

 

3) BATCH_STEP_EXECUTION

  • customExitStatusStep1
COLUMN VALUE
STEP_NAME customExitStatusStep1
EXIT_CODE COMPLETED
STATUS FAILED
JOB_EXECUTION_ID 19

 

  • customExitStatusStep2
COLUMN VALUE
STEP_NAME customExitStatusStep2
EXIT_CODE COMPLETED
STATUS COMPLETED
JOB_EXECUTION_ID 19

 

 

 

"PASS"로 종료되도록 설정해보자

CustomExitStatusConfiguration.java 의 customExitStatusStep2()
@Bean
public Step customExitStatusStep2() {
    return stepBuilderFactory.get("customExitStatusStep2")
            // 빈으로 등록해도되고, 이렇게 객체 생성해도 된다.
            .tasklet(new CustomTasklet())
            .listener(new PassCheckingListener())
            .build();
}

 

PassCheckingListener.java
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.StepExecutionListener;

public class PassCheckingListener implements StepExecutionListener {
    @Override
    public void beforeStep(StepExecution stepExecution) {

    }

    @Override
    public ExitStatus afterStep(StepExecution stepExecution) {
        // exit_status 셋팅
        String exitCode = stepExecution.getExitStatus().getExitCode();

        // FAILED 가 아니면
        if (!exitCode.equals(ExitStatus.FAILED.getExitCode())) {
            return new ExitStatus("PASS"); // 사용자 정의 코드 반환
        }
        
        return null;
    }
}

 

 

 

DB 테이블 조회

1) BATCH_JOB_EXECUTION

COLUMN VALUE
STATUS STOPPED
EXIT_CODE STOPPED
JOB_EXECUTION_ID 21

 

2) BATCH_JOB_INSTANCE

COLUMN VALUE
JOB_NAME customExitStatusJob

 

3) BATCH_STEP_EXECUTION

  • customExitStatusStep1
COLUMN VALUE
STEP_NAME customExitStatusStep1
EXIT_CODE COMPLETED
STATUS FAILED
JOB_EXECUTION_ID 21

 

  • customExitStatusStep2
COLUMN VALUE
STEP_NAME customExitStatusStep2
EXIT_CODE COMPLETED
STATUS PASS
JOB_EXECUTION_ID 21

 

 

 

STOPPED 상태

STOPPED 상태로 종료된 Job은 다시 시작할 수 있다. 중단된 위치에서 잡을 다시 시작할 수 있다.

 

https://devfunny.tistory.com/486?category=820618 

 

[스프링 배치] 잡의 종료 상태 설정 방법

잡의 종료 상태 스프링 배치의 잡은 종료 상태를 가진다. 잡 실행시 갖게되는 JobInstance 는 성공적으로 완료되면 두번 이상 실행될 수 없다. 이는 잡 이름과 파라미터로 식별된다. 만일 사용자가

devfunny.tistory.com

 

 

반응형

Designed by JB FACTORY