상세 컨텐츠

본문 제목

Spring Batch - Step 데이터 공유(Excution Context)

Spring/Spring Batch

by Chan.94 2022. 10. 13. 08:37

본문

반응형

Batch 실행 중 Step 간에 데이터를 공유해야만 하는 경우가 발생할 수 있다.

BATCH_JOB_EXECUTION_CONTEXT테이블의 SHORT_CONTEXT 컬럼에는 Job 공유 데이터 등의 정보를 문자열로 저장한다.

 

BATCH_JOB_EXECUTION_CONTEXT

CREATE TABLE BATCH_JOB_EXECUTION_CONTEXT  (
    JOB_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY,
    SHORT_CONTEXT VARCHAR(2500) NOT NULL,
    SERIALIZED_CONTEXT TEXT ,
    constraint JOB_EXEC_CTX_FK foreign key (JOB_EXECUTION_ID)
    references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
) ENGINE=InnoDB;

데이터 공유시 주의점 (중요)

SHORT_CONTEXT컬럼 사이즈는 2500Byte이고 JSON형태로 저장되기 때문에 크기를 염두하고 데이터를 공유해야 한다. 또한 Step 간에 데이터 공유를 할 수 있는 유일한 방법이어서 사이즈가 큰 데이터를 저장하면 오류를 초래할 수 있다.

따라서, 다음 Step에 결괏값들을 전달하지 않아도 되도록 설계하는 것이 바람직하다.

 

ChunkContext

실행 시점의 Job 상태를 제공한다.

Tasklet 내에서는 처리 중인 Chunk와 관련된 정보를 갖고 있으며, 해당 Chunk 정보는 Step&Job과 관련된 정보도 갖고 있다.

 

ExcutionContext

Spring Batch가 제공하는 ExcutionContext는 Job ExcutionContext, Step ExcutionContext 두 개가 있다.

 

Job ExcutionContext

통상적으로 Step처리의 결과값등을 다음 Step에 전달하는 것은 불가능하다. 그러나 Job ExcutionContext에 저장하면 어떤 Step에서도 참조 가능하게 할 수 있다.

 

Step ExcutionContext

Job ExcutionContext와 달리 다른 Step에서 참조가 불가능하다.

 


Job

@Configuration
public class ExampleJobConfiguration {

	@Autowired
	private JobBuilderFactory jobBuilderFactory;
	@Autowired
    private StepBuilderFactory stepBuilderFactory;
    
	@Bean
    public Job exampleJob(){

        Job customJob = jobBuilderFactory.get("exampleJob")
                .start(exampleStep())
                .next(exampleNextStep())
                .build();

        return customJob;
    }

    @Bean
    public Step exampleStep(){
        return stepBuilderFactory.get("exampleStep")
                .tasklet(new ExampleTasklet())
                .build();
    }
    
    @Bean
    public Step exampleNextStep(){
        return stepBuilderFactory.get("exampleNextStep")
                .tasklet(new ExampleNextTasklet())
                .build();
    }

}

Step

public class ExampleTasklet implements Tasklet{
	private final Logger logger = LoggerFactory.getLogger(this.getClass());

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

    	//STEP CONTEXT
    	StepContext stepContext = chunkContext.getStepContext();
    	
    	//Step들간의 데이터 공유
    	final ExecutionContext jobExecutionContext = stepContext.getStepExecution().getJobExecution().getExecutionContext();
    	
    	/*비즈니스 로직*/
    	int count = 0;
    	int index = 0;
    	
        while(true) {
        	logger.debug("[index] = " + index);
        	
        	index++;
        	count++;
        	
        	if(count == 10) {
        		break;
        	}
        }
        jobExecutionContext.put("dataShare", index);

        return RepeatStatus.FINISHED;
    }
}

public class ExampleNextTasklet implements Tasklet{
	private final Logger logger = LoggerFactory.getLogger(this.getClass());

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

    	//Step들간의 데이터 공유
    	final ExecutionContext jobExecutionContext = chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext();

    	/*비즈니스 로직*/
    	int count = 0;
    	int index = jobExecutionContext.getInt("dataShare");
    	
        while(true) {
        	logger.debug("[index] = " + index);
        	
        	index++;
        	count++;
        	
        	if(count == 10) {
        		break;
        	}
        }

        return RepeatStatus.FINISHED;
    }
}

BATCH_JOB_EXECUTION_CONTEXT

dataShare라는 공유 데이터가 저장된 것을 확인할 수 있다.

 

반응형

관련글 더보기

댓글 영역

>