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에 결괏값들을 전달하지 않아도 되도록 설계하는 것이 바람직하다.
실행 시점의 Job 상태를 제공한다.
Tasklet 내에서는 처리 중인 Chunk와 관련된 정보를 갖고 있으며, 해당 Chunk 정보는 Step&Job과 관련된 정보도 갖고 있다.
Spring Batch가 제공하는 ExcutionContext는 Job ExcutionContext, Step ExcutionContext 두 개가 있다.
통상적으로 Step처리의 결과값등을 다음 Step에 전달하는 것은 불가능하다. 그러나 Job ExcutionContext에 저장하면 어떤 Step에서도 참조 가능하게 할 수 있다.
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라는 공유 데이터가 저장된 것을 확인할 수 있다.
Spring Batch - Scheduler 등록 (0) | 2022.10.14 |
---|---|
Spring Batch - 메타 테이블 (0) | 2022.10.12 |
Spring Batch - Chunk 지향 프로세싱(Mybatis) (0) | 2022.10.11 |
Spring Batch - 개념, Tasklet Example(SimpleJob, FlowJob) (1) | 2022.10.04 |
댓글 영역