ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 23. Repeat
    BackEnd/Spring Batch 2022. 1. 4. 22:35
    반응형

      Spring Batch는 특정 조건이 충족될 때까지 (또는 특정 조건이 아직 충족되지 않을 때까지) Job 또는 Step을 반복하도록 배치 애플리케이션을 구성할 수 있습니다. Spring Batch에서는 Step의 반복과 Chunk 반복을 RepeatOperation을 사용해서 처리하며, 기본 구현체로 RepeatTemplate를 제공합니다.

     

    반복을 종료할 것인지 여부를 결정하는 세가지 항목

    RepeatStatus

    • 스프링 배치의 처리가 끝났는지 판별하기 위한 열거형(enum)
    • CONTINUABLE: 작업이 남아 있음, FINISHED: 더 이상의 반복 없음

     

    CompletionPolicy

    • RepeatTemplate의 iterate 메소드 안에서 반복을 중단할지 결정
    • 실행 횟수 또는 완료시기, 오류 발생 시 수행할 작업에 대한 반복여부 결정
    • 정상 종료를 알리는데 사용

    구현 클래스

    • SimpleCompletionPolicy: 현재 반복 횟수가 Chunk 개수보다 크면 반복 종료
    • CountingCompletionPolicy: 일정한 카운트를 계산 및 집계해서 카운트 제한 조건이 만족하면 반복 종료
    • SimpleCompletionPolicy: 반복시점부터 현재시점까지 소요된 시간이 설정된 시간보다 크면 반복 종료

     

    ExceptionHandler

    • RepeatCallback 안에서 예외가 발생하면 RepeatTemplate가 ExceptionHandler를 참조해서 예외를 다시 던질지 여부 결정
    • 예외를 받아서 다시 던지게 되면 반복 종료
    • 비정상 종료를 알리는데 사용

    구현 클래스

    • SimpleLimitExceptionHandler: 예외 타입 중 하나가 발견되면 카운터가 증가하고 한계가 초과되었는지 여부를 확인하고 Throwable을 다시 던짐
    • LogOrRethrowExceptionHandler: 예외를 로그로 기록할지 아니면 다시 던질 지 결정
    • RethrowOnThresholdExceptionHandler: 지정된 유형의 예외가 임계 값에 도달하면 다시 발생
    package io.springbatch.springbatchlecture;
    
    import lombok.RequiredArgsConstructor;
    import org.springframework.batch.core.*;
    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.item.*;
    import org.springframework.batch.item.adapter.ItemWriterAdapter;
    import org.springframework.batch.item.support.ClassifierCompositeItemProcessor;
    import org.springframework.batch.item.support.CompositeItemProcessor;
    import org.springframework.batch.item.support.builder.CompositeItemProcessorBuilder;
    import org.springframework.batch.repeat.CompletionPolicy;
    import org.springframework.batch.repeat.RepeatCallback;
    import org.springframework.batch.repeat.RepeatContext;
    import org.springframework.batch.repeat.RepeatStatus;
    import org.springframework.batch.repeat.exception.SimpleLimitExceptionHandler;
    import org.springframework.batch.repeat.policy.CompositeCompletionPolicy;
    import org.springframework.batch.repeat.policy.SimpleCompletionPolicy;
    import org.springframework.batch.repeat.policy.TimeoutTerminationPolicy;
    import org.springframework.batch.repeat.support.RepeatTemplate;
    import org.springframework.classify.PatternMatchingClassifier;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    @RequiredArgsConstructor
    @Configuration
    public class RepeatConfiguration {
    
        private final JobBuilderFactory jobBuilderFactory;
        private final StepBuilderFactory stepBuilderFactory;
    
        @Bean
        public Job job() throws Exception {
            return jobBuilderFactory.get("batchJob")
                    .incrementer(new RunIdIncrementer())
                    .start(step1())
                    .build();
        }
    
        @Bean
        public Step step1() throws Exception {
            return stepBuilderFactory.get("step1")
                    .<String, String>chunk(5)
                    .reader(new ItemReader<String>() {
                        int i = 0;
                        @Override
                        public String read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
                            i++;
                            return i > 3 ? null : "item" + i;
                        }
                    })
                    .processor(new ItemProcessor<String, String>() {
    
                        RepeatTemplate template = new RepeatTemplate();
    
                        @Override
                        public String process(String item) throws Exception {
    
                            // 반복할 때마다 count 변수의 값을 1씩 증가
                            // count 값이 chunkSize 값보다 크거나 같을 때 반복문 종료
    //                        template.setCompletionPolicy(new SimpleCompletionPolicy(2));
                            // 소요된 시간이 설정된 시간보다 클 경우 반복문 종료
    //                        template.setCompletionPolicy(new TimeoutTerminationPolicy(3000));
    
                            // 여러 유형의 CompletionPolicy 를 복합적으로 처리함
                            // 여러 개 중에 먼저 조건이 부합하는 CompletionPolicy 에 따라 반복문이 종료됨
    //                        CompositeCompletionPolicy completionPolicy = new CompositeCompletionPolicy();
    //                        CompletionPolicy[] completionPolicies = new CompletionPolicy[]{new TimeoutTerminationPolicy(3000),new SimpleCompletionPolicy(2)};
    //                        completionPolicy.setPolicies(completionPolicies);
    //                        template.setCompletionPolicy(completionPolicy);
    
                            // 예외 제한 횟수만큼 반복문 실행
    //                        template.setExceptionHandler(simpleLimitExceptionHandler());
    
                            template.iterate(new RepeatCallback() {
    
                                public RepeatStatus doInIteration(RepeatContext context) {
                                   System.out.println("repeatTest");
    //                               throw new RuntimeException("Exception is occurred");
                                    return RepeatStatus.CONTINUABLE;
                                }
    
                            });
    
                            return item;
                        }
                    })
                    .writer(new ItemWriter<String>() {
                        @Override
                        public void write(List<? extends String> items) throws Exception {
                            System.out.println(items);
                        }
                    })
                    .build();
        }
    
        @Bean
        public SimpleLimitExceptionHandler simpleLimitExceptionHandler(){
            return new SimpleLimitExceptionHandler(2);
        }
    }

     

    [참고자료]

    인프런-스프링 배치 - Spring Boot 기반으로 개발하는 Spring Batch

     

     

    반응형

    'BackEnd > Spring Batch' 카테고리의 다른 글

    25. Skip  (0) 2022.01.06
    24. FaultTolerant  (0) 2022.01.04
    22. ItemProcessor  (0) 2022.01.04
    21. ItemWriterAdapter  (0) 2021.12.31
    20. ItemWriter (DB)  (0) 2021.12.31

    댓글

Designed by Tistory.