ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • StepContribution 와 ChunkContext[Spring batch]
    Spring/Spring Batch 2024. 8. 7. 10:23
    728x90
    반응형

    Spring Batch에서 StepContribution과 ChunkContext는 배치 처리에서 중요한 역할을 합니다. 이 두 객체는 배치 작업의 상태를 추적하고, 각 청크(chunk) 및 단계(step)의 실행 정보를 제공합니다.

    StepContribution

    StepContribution은 단계의 기여도를 나타내며, 특정 단계가 얼마나 많은 데이터를 읽고 처리했는지 등의 통계를 포함합니다. 이 객체는 주로 배치 작업의 진행 상황을 모니터링하고 기록하는 데 사용됩니다.

    ChunkContext

    ChunkContext는 청크 수준에서의 컨텍스트 정보를 제공합니다. 청크는 읽기-처리-쓰기 작업의 단위이며, ChunkContext는 청크 처리 중에 발생하는 상태 정보를 유지합니다.

     

    예제 시나리오

    실생활 예제로는 은행의 거래 기록을 처리하는 배치 작업을 생각해 볼 수 있습니다. 이 작업은 여러 단계로 구성될 수 있으며, 각 단계는 특정 작업을 수행합니다. 예를 들어, 거래 데이터를 읽고, 처리하고, 데이터베이스에 쓰는 단계를 포함할 수 있습니다.

    StepContribution과 ChunkContext 사용 예제

    아래는 Spring Batch를 사용하여 거래 데이터를 처리하는 예제입니다. 이 예제에서는 StepContribution과 ChunkContext를 사용하여 단계와 청크의 상태를 기록합니다.

     

     

    2. Job Configuration

    배치 작업(Job)을 구성하는 설정 클래스를 작성합니다.

     

     

    import org.springframework.batch.core.Job;
    import org.springframework.batch.core.Step;
    import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
    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.scope.context.StepContext;
    import org.springframework.batch.core.step.tasklet.Tasklet;
    import org.springframework.batch.core.step.tasklet.TaskletStep;
    import org.springframework.batch.item.ItemProcessor;
    import org.springframework.batch.item.ItemReader;
    import org.springframework.batch.item.ItemWriter;
    import org.springframework.batch.item.support.ListItemReader;
    import org.springframework.batch.item.support.ListItemWriter;
    import org.springframework.batch.repeat.RepeatStatus;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import java.util.Arrays;
    import java.util.List;
    
    @Configuration
    @EnableBatchProcessing
    public class BatchConfig {
    
        @Autowired
        private JobBuilderFactory jobBuilderFactory;
    
        @Autowired
        private StepBuilderFactory stepBuilderFactory;
    
        @Bean
        public Job transactionJob() {
            return jobBuilderFactory.get("transactionJob")
                    .incrementer(new RunIdIncrementer())
                    .start(readAndProcessStep())
                    .next(reportingStep())
                    .build();
        }
    
        @Bean
        public Step readAndProcessStep() {
            return stepBuilderFactory.get("readAndProcessStep")
                    .<String, String>chunk(2)
                    .reader(itemReader())
                    .processor(itemProcessor())
                    .writer(itemWriter())
                    .listener(new CustomChunkListener())
                    .build();
        }
    
        @Bean
        public Step reportingStep() {
            return stepBuilderFactory.get("reportingStep")
                    .tasklet(new ReportingTasklet())
                    .build();
        }
    
        @Bean
        public ItemReader<String> itemReader() {
            List<String> items = Arrays.asList("transaction1", "transaction2", "transaction3", "transaction4");
            return new ListItemReader<>(items);
        }
    
        @Bean
        public ItemProcessor<String, String> itemProcessor() {
            return item -> {
                // 간단한 처리 로직
                return item.toUpperCase();
            };
        }
    
        @Bean
        public ItemWriter<String> itemWriter() {
            return new ListItemWriter<>();
        }
    
        public static class ReportingTasklet implements Tasklet {
    
            @Override
            public RepeatStatus execute(org.springframework.batch.core.StepContribution contribution, ChunkContext chunkContext) throws Exception {
                // 보고서 생성 로직
                StepContext stepContext = chunkContext.getStepContext();
                System.out.println("Reporting Tasklet executed");
                return RepeatStatus.FINISHED;
            }
        }
    }

     

    3. CustomChunkListener

    StepContribution과 ChunkContext를 사용하는 커스텀 청크 리스너를 작성합니다.

     

    import org.springframework.batch.core.ChunkListener;
    import org.springframework.batch.core.StepContribution;
    import org.springframework.batch.core.scope.context.ChunkContext;
    import org.springframework.batch.core.scope.context.StepContext;
    
    public class CustomChunkListener implements ChunkListener {
    
        @Override
        public void beforeChunk(ChunkContext context) {
            System.out.println("Before chunk: " + context.getStepContext().getStepName());
        }
    
        @Override
        public void afterChunk(ChunkContext context) {
            StepContext stepContext = context.getStepContext();
            StepContribution contribution = stepContext.getStepExecution().getStepContribution();
            System.out.println("After chunk: " + stepContext.getStepName() + ", readCount: " + contribution.getReadCount());
        }
    
        @Override
        public void afterChunkError(ChunkContext context) {
            System.out.println("After chunk error: " + context.getStepContext().getStepName());
        }
    }

     

    이 예제에서는 다음과 같은 작업을 수행합니다.

    1. BatchConfig 클래스: 배치 작업과 단계를 설정합니다. readAndProcessStep 단계는 데이터 읽기, 처리 및 쓰기 작업을 수행합니다. reportingStep 단계는 보고서를 생성하는 작업을 수행합니다.
    2. CustomChunkListener 클래스: 청크 작업 전후에 호출되는 리스너로, StepContribution과 ChunkContext를 사용하여 청크의 상태를 기록합니다.
    3. ReportingTasklet 클래스: 간단한 테스크릿을 구현하여 보고서 생성 작업을 수행합니다.

     

    실행

    배치 작업을 실행하면 다음과 같은 로그 출력이 나타납니다.

     

    Before chunk: readAndProcessStep
    After chunk: readAndProcessStep, readCount: 2
    Before chunk: readAndProcessStep
    After chunk: readAndProcessStep, readCount: 2
    Reporting Tasklet executed

     

    이 로그는 각 청크 처리 전후와 보고서 생성 작업의 실행을 보여줍니다. StepContribution 객체를 통해 각 청크의 읽기 횟수를 기록할 수 있습니다.

    위의 예제는 StepContribution과 ChunkContext를 사용하여 배치 작업의 각 단계와 청크의 상태를 추적하고 기록하는 방법을 보여줍니다. 이러한 정보를 활용하여 배치 작업의 상태를 모니터링하고, 문제가 발생했을 때 디버깅할 수 있습니다.

    728x90
    반응형

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

    Tasklet과 ItemReader, ItemProcessor, ItemWriter란?  (0) 2024.07.26
Designed by Tistory.