Study/Spring Batch

스프링 배치 실행 -tasklet(), startLimit()/allowStartIfComplete()

공29 2024. 4. 22. 22:47

1. tasklet()

1) 기본개념

  • Tasklet 타입의 클래스를 설정한다.
    • Step 내에서 구성되고 실행되는 도메인 객체로서 주로 단일 태스크를 수행하기위한 것.
    • TaskletStep 에 의해 반복적으로 수행되며 반환값에 따라 계속 수행 혹은 종료한다.
    • RepeatStatus - Tasklet 의 반복 여부 상태 값
      • RepeatStatus.FINISHED - Tasklet 종료, RepeatStatus 을 null 로 반환하면 RepeatStatus.FINISHED로 해석됨.
      • RepeatStatus.CONTINUABLE - Tasklet 반복.
      • RepeatStatus.FINISHED가 리턴되거나 실패 예외가 던져지기 전까지 TaskletStep 에 의해 while 문 안에서 반복적으로 호출됨. (무한루프 주의)
  • 익명 클래스 혹은 구현 클래스를 만들어서 사용한다.
  • 이 메소드를 실행하게 되면 TaskletStepBuilder 가 반환되어 관련 API 를 설정할 수 있다.
  • Step 에 오직 하나의 Tasklet 설정이 가능하며 두개 이상을 설정 했을 경우 마지막에 설정한 객체가 실행된다.

 

2) 구조

 

3) 사용

3-1) 익명 클래스 작성

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

 

3-2) Tasklet interface를 구현한 클래스 생성

@Component
public class CustomTasklet implements Tasklet {

    @Override
    public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {

        System.out.println("stepContribution = " + stepContribution + ", chunkContext = " + chunkContext);

        return RepeatStatus.FINISHED;
    }
}
@Bean
public Step step2() {
    return stepBuilderFactory.get("step2")
            .tasklet(customTasklet)
            .build();
}

 

2. startLimit()

1) 기본 개념

  • Step의 실행 횟수를 조정할 수 있다.
  • Step 마다 설정할 수 있다.
  • 설정 값을 초과해서 다시 실행하려고 하면 StartLimitExceededException이 발생한다.
  • start-limit의 디폴트 값은 Integer.MAX_VALUE. (거의 무한...)

 

2) 사용

@Bean
public Step step2() {
    return stepBuilderFactory.get("step2")
            .tasklet(new Tasklet() {
                @Override
                public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
                    System.out.println("stepContribution = " + stepContribution + ", chunkContext = " + chunkContext);
                    throw new RuntimeException(""); // 고의로 Job 실패 발생
//                    return RepeatStatus.FINISHED;
                }
            })
            .startLimit(3) // 세 번만 실행 가능
            .build();
}

startLimit 설정을 통해 실행 횟수를 정할 수 있다. 실행 횟수 초과시 다음과 같은 오류가 발생한다.

org.springframework.batch.core.StartLimitExceededException: Maximum start limit exceeded for step: step2StartMax: 3

 

3. allowStartIfComplete()

1) 기본 개념

  • 재시작 가능한 Job 에서 Step 의 이전 성공 여부와 상관없이 항상 step 을 실행하기 위한 설정.
  • 실행 마다 유효성을 검증하는 Step이나 사전 작업이 꼭 필요한 Step 등...
  • 기본적으로 COMPLETED 상태를 가진 Step 은 Job 재 시작 시 실행하지 않고 스킵한다.
  • allow-start-if-complete가 “true”로 설정된 step은 항상 실행한다.

 

2) 흐름도

 

3) 사용

@Bean
public Step step1() {
    return stepBuilderFactory.get("step1")
            .tasklet(new Tasklet() {
                @Override
                public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
                    System.out.println("stepContribution = " + stepContribution + ", chunkContext = " + chunkContext);
                    return RepeatStatus.FINISHED;
                }
            })
            .allowStartIfComplete(true)
            .build();
}