본문 바로가기

Batch

Spring Batch에 대해 알아보자 - (2) Step, StepExecution, StepContribution

 

Step이란?

Job은 여러 Step을 통해 구성되어 있다.

  • Job을 구성하는 실행 단위
  • Job은 여러 Step으로 나뉘고, Step들이 순차적으로 혹은 조건/분기에 따라 실행됩니다.
  • Step은 내부적으로 읽기(Reader) → 처리(Processor) → 쓰기(Writer) 구조를 갖거나, 단순히 한 번의 로직을 실행할 수도 있습니다.

즉, Step은 Job의 작은 처리 과정 중 하나 입니다.


Step의 종류

Spring Batch에서 Step은 크게 두 가지 방식으로 구현할 수 있습니다. (실제로는 더 많은 구현 방식이 있습니다.)

Tasklet vs ChunkOrientedTasklet

(1) TaskletStep

  • Tasklet 인터페이스를 구현해서 한 번 실행되는 작업을 정의
  • 주로 간단한 로직(로그 찍기, 파일 삭제, API 호출 등)에 적합
@Bean
public Step taskletStep(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
    return new StepBuilder("taskletStep", jobRepository)
            .tasklet((contribution, chunkContext) -> {
                System.out.println("Tasklet Step 실행");
                return RepeatStatus.FINISHED;
            }, transactionManager)
            .build();
}

 

 

 

(2) Chunk-Oriented Step 

  • 대량 데이터 처리를 위해 사용
  • Reader → Processor → Writer 구조
  • 지정한 크기(chunk 단위)만큼 데이터를 읽고, 처리한 뒤, 한꺼번에 Writer로 저장
@Bean
public Step chunkStep(JobRepository jobRepository, 
                      PlatformTransactionManager transactionManager,
                      ItemReader<String> reader,
                      ItemProcessor<String, String> processor,
                      ItemWriter<String> writer) {
    return new StepBuilder("chunkStep", jobRepository)
            .<String, String>chunk(5, transactionManager) // 5개 단위로 처리
            .reader(reader)
            .processor(processor)
            .writer(writer)
            .build();
}

 

실행 흐름 예시 (chunk=5):

  1. Reader가 데이터 5건 읽음
  2. Processor가 5건 처리
  3. Writer가 5건 저장
  4. 다시 Reader 실행 → 반복

StepExecution이란?

  • Step의 실행 정보를 담는 객체입니다.
  • Step이 실행될 때마다 새로운 StepExecution이 생성됩니다.
  • 실행 상태, 시작/종료 시간, 읽은 건수, 처리한 건수, 에러 여부 등을 기록합니다.

즉, StepExecution은 Step 실행의 로그/메타데이터 역할을 하는 객체입니다.


JobExecution과의 관계

JobExecution과 StepExecution

  • JobExecution 안에는 여러 개의 StepExecution이 포함됩니다.
  • JobExecution이 Job 실행 전체의 결과를 관리한다면, StepExecution은 개별 Step 실행 결과를 관리합니다.
    • StepExecution이 실패하면 JobExecution도 실패하게 됩니다.
    • 또한 StepExectuon이 실패하게 되면 이후 실행되는 Step들은 실행되지 않고, StepExecution도 생성되지 않습니다.
    • 실패한 Step과 실행되지 않은 Step들은 재실행이 가능합니다. (성공한 Step은 재실행시 제외 됩니다.)

예시 구조:

JobExecution #1
 ├─ StepExecution #1 (step1 성공, read=1000, write=1000)
 ├─ StepExecution #2 (step2 실패, read=500, write=300)
 └─ StepExecution #3 (step3 미실행, read=0, write=0)

StepContribution이란?

  • Step 실행 과정에서 Chunk 단위 처리 결과를 누적·집계하는 객체입니다.
  • 즉, 한 번의 청크 처리에서 “몇 개 읽었는지, 몇 개 썼는지, 몇 개 건너뛰었는지”를 StepExecution에 전달하는 역할을 합니다.
  • StepContribution은 개별 Chunk 실행 중간 상태를 담고, 최종적으로 StepExecution이 이를 모아 Step 전체의 통계로 기록합니다.

StepContribution 동작 과정

  • StepContribution = StepExecution에 전달될 Chunk 실행의 중간 결과
  • Chunk 단위에서의 read/write/skip/filter 건수를 누적하고 상태를 반영
  • 최종적으로 StepExecution이 Step 전체 실행 결과를 관리
  • 개발자가 직접 다룰 일은 많지 않지만, Tasklet 구현 시 execute() 메서드 파라미터로 활용 가능

StepExecution과의 관계

  • StepExecution은 Step 전체 실행 결과를 관리합니다.
  • StepContribution은 그 Step을 이루는 작은 단위(청크)의 실행 결과를 기록합니다.

흐름으로 보면:

Chunk 실행 (Reader → Processor → Writer)
   └─ StepContribution (한 청크에서 처리된 건수, 스킵 수 등)
         └─ StepExecution에 누적

 


StepContribution  구성 정보

대표적으로 다음과 같은 값들을 관리합니다.

  • readCount: Reader가 읽은 아이템 수
  • writeCount: Writer가 쓴 아이템 수
  • filterCount: Processor에서 필터링된 아이템 수
  • skipCount: 예외로 인해 건너뛴 아이템 수
  • exitStatus: 현재 Chunk 실행에 대한 상태

이 정보들은 최종적으로 StepExecution에 반영되어 JobExecution까지 집계됩니다.