아래 글은 한국 스프링 사용자 모임(KSUG)에서 진행된 스프링 배치 스터디 내용을 정리한 게시글입니다.
DEVOCEAN에 연재 중인 KIDO님의 글을 참고하여 실습한 내용을 기록했습니다.
원본: [SpringBatch 연재 10] 스프링배치 플로우 컨트롤 하기
Spring Batch에서 flow 컨트롤은 Job 내에서 Step들의 실행 순서와 조건을 제어하는 기능입니다.
FlowBuilder API를 사용하여 설정할 수 있습니다.
주요 API
Flow 컨트롤을 위해 Spring Batch에서 제공하는 주요 API들은 다음과 같습니다.
- next(): 순차적으로 Step들을 연결시킬 때 사용합니다.
- on(): 특정 ExitStatus를 감지하여 해당 상태에 따라 흐름을 제어할 때 사용합니다.
- to(): 다음으로 이동할 Step을 지정합니다.
- from(): 이벤트 리스너로서, 다음 단계로 넘어가는 조건을 추가로 설정할 때 사용합니다.
- end(): Flow의 종료를 나타냅니다.
next
next()는 다음의 Step으로 이동시키기 위해 사용합니다.
/**
* 메인 job 실행 메서드
*/
@Bean
public Job nextStepJob(Step step01, Step step02, JobRepository jobRepository) {
log.info("------------------ Init myJob -----------------");
return new JobBuilder(NEXT_STEP_TASK, jobRepository)
.incrementer(new RunIdIncrementer())
.start(step01)
.next(step02)
.build();
}
@Bean(name = "step01")
public Step step01(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
log.info("------------------ Init myStep -----------------");
return new StepBuilder("step01", jobRepository)
.tasklet((contribution, chunkContext) -> {
log.info("Execute Step 01 Tasklet ...");
return RepeatStatus.FINISHED;
}, transactionManager)
.build();
}
@Bean(name = "step02")
public Step step02(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
log.info("------------------ Init myStep -----------------");
return new StepBuilder("step02", jobRepository)
.tasklet((contribution, chunkContext) -> {
log.info("Execute Step 02 Tasklet ...");
return RepeatStatus.FINISHED;
}, transactionManager)
.build();
}
on과 from
step의 종료 조건에 따라 어떤 Step으로 이동할지 결정할 수 있도록 합니다.
- 아래 예시 코드는 step1을 먼저 수행하고, 해당 결과에 따라서 다음 스텝으로 이동합니다.
@Bean
public Job job() {
return jobBuilderFactory.get("job")
.start(step1())
.on("FAILED").to(step3()) // 작업이 실패 할 경우 step3 호출
.from(step1()).on("COMPLETED").to(step2()) // step1 작업이 완료 될 경우 step2 호출
.end()
.build();
}
stop
- 특정 step의 작업 결과 상태를 확인하고 정지합니다.
@Bean
public Job job() {
return jobBuilderFactory.get("job")
.start(step1()) // step1의 결과가 실패일 경우 배치 작업을 정지
.on("FAILED").stop()
.end()
.build();
}
job의 실패를 유도하는 예시로 짝/홀수를 사용해 볼 수 있습니다.
@Bean(name = "step01")
public Step step01(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
log.info("------------------ Init myStep -----------------");
return new StepBuilder("step01", jobRepository)
.tasklet((contribution, chunkContext) -> {
log.info("Execute Step 01 Tasklet ...");
Random random = new Random();
int randomValue = random.nextInt(1000);
if (randomValue % 2 == 0) {
return RepeatStatus.FINISHED;
}
throw new RuntimeException("Error This value is Odd: " + randomValue);
}, transactionManager)
.build();
}
stop 예제의 실행 결과
1. 짝수 였을 때
step01 실행 후 step02가 실행됩니다.
2024-12-16T20:27:02.031 INFO Job 'NEXT_STEP_TASK' started with parameters: {'run.id': 2}
2024-12-16T20:27:02.058 INFO Executing step: 'step01'
2024-12-16T20:27:02.068 INFO Step 01 Tasklet started
2024-12-16T20:27:02.068 INFO Random value: 720
2024-12-16T20:27:02.074 INFO Step 'step01' executed in 14ms
2024-12-16T20:27:02.092 INFO Executing step: 'step02'
2024-12-16T20:27:02.099 INFO Step 02 Tasklet started
2024-12-16T20:27:02.104 INFO Step 'step02' executed in 11ms
2024-12-16T20:27:02.112 INFO Job 'NEXT_STEP_TASK' completed with status: COMPLETED (Total time: 71ms)
2. 홀수 였을 때
step01에서 에러가 발생하고 그대로 종료됩니다.
2024-12-16T20:28:00.820 INFO Job 'NEXT_STEP_TASK' started with parameters: {'run.id': 5}
2024-12-16T20:28:00.849 INFO Executing step: 'step01'
2024-12-16T20:28:00.859 INFO Step 01 Tasklet started
2024-12-16T20:28:00.859 INFO Random value: 729
2024-12-16T20:28:00.861 ERROR Error occurred in 'step01': java.lang.RuntimeException: Error This value is Odd: 729
2024-12-16T20:28:00.865 INFO Step 'step01' completed in 15ms
2024-12-16T20:28:00.877 INFO Job 'NEXT_STEP_TASK' stopped with status: STOPPED (Total time: 47ms)
'알아두면 좋은 개발 지식 > Spring Batch 스터디' 카테고리의 다른 글
[9회차] 입맛에 맞는 배치 처리를 위한 Custom ItemReader/ItemWriter 구현방법 알아보기 (9) | 2024.12.14 |
---|---|
[8회차] CompositeItemProcessor 으로 여러단계에 걸쳐 데이터 Transform하기 (1) | 2024.11.28 |
[7회차] Spring Batch 스터디: 후기 및 추가 학습 내용 (4) | 2024.11.20 |
[7회차] MyBatisPagingItemReader로 DB내용을 읽고, MyBatisItemWriter로 DB에 쓰기 (3) | 2024.11.16 |
[6회차] Spring Batch 스터디: 후기 및 추가 학습 내용 (2) | 2024.11.16 |