spring batch 기본 내용 정리

스프링 배치(Spring Batch)를 시작할 때 가장 먼저 하는 작업은 하나의 배치 Job을 정의하고 이를 빈(bean)으로 등록하는 것입니다.  
보통 @Configuration 어노테이션이 선언된 설정 클래스에서 Job과 Step을 정의하게 됩니다.

Spring Batch 5.1 이전 vs 이후의 차이

@Configuration
public class MyJobConfig {
    
    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Bean
    public Job sampleJob() {
        return jobBuilderFactory.get("sampleJob")
            .start(stepBuilderFactory.get("step1")
                .tasklet((contribution, chunkContext) -> {
                    System.out.println("Hello, Spring Batch!");
                    return RepeatStatus.FINISHED;
                }).build())
            .build();
    }
}

하지만 Spring Batch 5.1부터는 JobBuilderFactory, StepBuilderFactory는 deprecated 되었고,
직접 JobBuilder와 StepBuilder를 생성해야 합니다. 이때 중요한 점은 JobRepository를 명시적으로 주입해야 한다는 것입니다.

Spring Batch 5.1 이후 방식

@Configuration
public class MyJobConfig {

    @Bean
    public Job sampleJob(JobRepository jobRepository) {
        return new JobBuilder("sampleJob", jobRepository)
            .start(step1(jobRepository))
            .build();
    }

    public Step step1(JobRepository jobRepository) {
        return new StepBuilder("step1", jobRepository)
            .tasklet((contribution, chunkContext) -> {
                System.out.println("Spring Batch 5.1 방식");
                return RepeatStatus.FINISHED;
            }).build();
    }
}

왜 이렇게 바뀌었을까?

JobBuilderFactory, StepBuilderFactory는 내부적으로 @Autowired에 의존했기 때문에,
명시적인 의존성 주입의 명확성과 프레임워크 구성요소 분리를 강화하기 위한 방향으로 변경되었습니다. 또한 이러한 변경은 향후 코틀린 DSL (JobBuilder, StepBuilder 를 직접 넘기면 DSL 형태로 쓰기 쉬움), 모듈화된 Job 구성, 테스트 편의성에도 도움이 됩니다. 

 

스프링 배치 동작 

Spring Batch는 기본적으로 아래 구조로 동작합니다.

Job --> Step --> Tasklet(또는 Chunk)

  • Job: 하나의 배치 단위 작업. 전체 흐름을 정의합니다.
  • Step: Job을 구성하는 하나의 단계. 각 Step은 독립적으로 실행됩니다.
  • Tasklet: Step 내에서 수행할 단일 작업 단위입니다. 보통 tasklet() 메서드로 정의합니다.
@Bean
public Job myJob(JobRepository jobRepository) {
    return new JobBuilder("myJob", jobRepository)
        .start(myStep(jobRepository))
        .build();
}

public Step myStep(JobRepository jobRepository) {
    return new StepBuilder("myStep", jobRepository)
        .tasklet((contribution, chunkContext) -> {
            System.out.println("Step 실행 중...");
            return RepeatStatus.FINISHED;
        }).build();
}

위 코드처럼 Job을 실행하면 내부적으로 Step이 실행되고, Step 안에서 Tasklet이 호출되어 로직이 실행됩니다.

 

배치 실행 이력 관리: Spring Batch 메타 테이블

Spring Batch는 Job/Step의 실행을 관리하기 위해 자체적으로 메타 테이블 스키마를 제공합니다.

실행에 대한 성공 및 실패 여부등을 관리해서 배치 운용에 빠른 대처를 가능하게 한다. 

왜 중요한가?

  • Job/Step의 성공/실패 여부를 기록하고 추적할 수 있어, 실패 복구(Retry)나 재시작(Restart)에 매우 유용합니다.
  • 운영 환경에서는 실패 이력, 파라미터 변경, 중복 실행 방지 등의 기능이 핵심입니다.

https://docs.spring.io/spring-batch/docs/3.0.x/reference/html/metaDataSchema.html

 

Job 관련 테이블

BATCH_JOB_INSTANCE 

  • 역할: Job의 논리적 실행 단위인 JobInstance 정보를 저장
  • 주요 컬럼: JOB_NAME, JOB_KEY
  • 특징:
    • 동일한 Job 이름과 동일한 JobParameter 조합이면 하나의 JobInstance로 판단
    • 즉, JobInstance는 중복 실행되지 않음

예: jobA라는 Job에 "date"=2024-06-01이라는 파라미터로 실행했다면,
같은 이름과 파라미터로는 중복 실행 불가 → JobInstanceAlreadyCompleteException 발생 가능

BATCH_JOB_EXECUTION

 

  • 역할: Job의 실제 실행 이력을 저장
  • 주요 컬럼: START_TIME, END_TIME, STATUS, EXIT_CODE 등
  • 특징:
    • 하나의 JobInstance에 대해 여러 번 실행될 수 있음 (예: 실패 → 재시작)
    • 실행 상태 및 예외 메시지 등을 함께 기록

 

BATCH_JOB_EXECUTION_PARAMS

 

  • 역할: 실행 당시 사용된 JobParameters를 저장
  • 주요 컬럼: PARAMETER_NAME, PARAMETER_TYPE, PARAMETER_VALUE
  • 특징:
    • JobInstance의 고유성을 판단하는 기준이 됨

 

BATCH_JOB_EXECUTION_CONTEXT 

  • 역할: Job 실행 중 사용되는 상태 정보, 공유 데이터를 저장 (Map 구조)
  • 특징:
    • 내부적으로 java.util.Map<String, Object> 형태
    • **직렬화(Serialization)**된 형태로 DB에 저장됨
    • Step 간 공유 데이터를 전달할 때 사용 가능

예: 특정 Step에서 만든 데이터를 다음 Step에서 참조해야 할 때 Context 활용

Step 관련 테이블

BATCH_STEP_EXECUTION 

  • 역할: 각 Step의 실행 이력 정보를 저장
  • 주요 컬럼: STEP_NAME, START_TIME, END_TIME, STATUS, EXIT_MESSAGE
  • 특징:
    • 하나의 JobExecution 안에 여러 개의 StepExecution이 연결될 수 있음
    • 실행 상태, 실패 메시지, 처리한 아이템 수, 예외 정보 등도 포함

예: ChunkStep에서는 READ_COUNT, WRITE_COUNT, SKIP_COUNT 등의 통계도 포함됨

BATCH_STEP_EXECUTION_CONTEXT 

  • 역할: Step 실행 중 사용하는 상태 정보와 공유 데이터(Map 형태) 저장
  • 특징:
    • 내부적으로 Map<String, Object> 구조를 직렬화해서 DB에 저장
    • Step 내부 혹은 Tasklet/ItemReader/Writer 간 공유 용도로 사용 가능

예: 현재 Step의 처리 위치, 리트라이 횟수 등을 기록해서 실패 복구 시 이어서 재처리 가능

 

Job

Spring Batch의 최상위 개념: Job

Spring Batch에서 Job은 배치 계층 구조의 최상위 개념입니다.  
하나의 Job은 전체 배치 작업 단위를 의미하며, 여러 개의 Step을 포함할 수 있습니다.

Job 인터페이스

  • Job은 Spring Batch에서 배치 실행을 위한 최상위 인터페이스입니다.
  • Job은 JobExecution을 통해 실행되며, 실행 상태/파라미터/컨텍스트 등을 관리합니다.
  • 스프링은 이 인터페이스에 대한 기본 구현체를 제공합니다.

 

기본 구현체 소개

SimpleJob

가장 일반적으로 사용되는 Job 구현체

Step들을 순차적으로 실행함

내부적으로 Step을 순서대로 순회하며 처리

예: step1 → step2 → step3 순차 실행

FlowJob

조건 분기, 흐름 제어가 필요한 경우 사용

Flow, FlowBuilder, JobFlowExecutor 등을 사용해 Step 간의 흐름을 정의 가능

예: step1 → (성공 시) step2, 실패 시 → step3 와 같은 조건 분기 흐름


Job 구현 구조

Spring Batch의 기본 Job 구현체들은 내부적으로 AbstractJob을 상속합니다.

public abstract class AbstractJob implements Job {
    private String name;
    private JobParametersIncrementer incrementer;
    private JobExecutionListener listener;
    private JobRepository jobRepository;
    ...
}

AbstractJob이 제공하는 기능들

  • Job 이름 설정
  • Job 재시작 여부 판단 (isRestartable)
  • JobExecutionListener로 이벤트 처리
  • 메타데이터 저장을 위한 JobRepository 연동

 

JobInstance

Job이 실행될 때 생성되는 Job 의 논리적 실행 단위 객체로서 고유하게 식별 가능한 작업 실행 

예를 들어 하루에 한 번 씩 배치 Job이 실행된다면 매일 실행되는 각각의 Job을 JobInstance 로 표현한다. 

여기서 주의할 점은 

JobRepository 에서 

처음 시작하는 Job + JobParameter 일 경우 새로운 JobInstance 생성

이전과 동일한 Job + JobParameter 으로 실행 할 경우 이미 존재하는 JobInstance 리턴

 

JobParameter

Job을 실행할 때 함께 포함되어 사용되는 파라미터를 가진 도메인 객체

JobParameters 와 JobInstace 는 1:1 관계 

생성 및 바인딩

Java -jar xxx.jar requestDate=20250601

@Value("#{jobParameter[requestDate]}") (@JobScope, @StepScope 선언 필수)

 

JobExecution 

JobInstance 에 대한 Job 실행 중에 발생한 정보들을 저장하고 있는 객체 

시작시간, 종료시간, 상태(시작됨, 완료, 실패), 종료상태의 속성을 가짐

JobInstance 과의 관계

JobExecution 은 Failed, Completed 등의 Job의 실행 결과 상태를 가지고 있다. 

JobExecution 의 실행 상태 결과가 Completed 면 JobInstance 실행이 완료된 것으로 간주해서 재 실행이 불가함

JobExecution 의 실행 상태 결과가 Failed 면 JobInstance 실행이 완료되지 않은 것으로 간주해서 재실행이 가능함

JobParameter 가 동일한 값으로 Job을 실행할지라도 JobInstance 를 계속 실행할 수 있음

JobExecution 의 실행 상태 결과가 Completed 될 때까지 하나의 JobInstance 내에 여러 번의 시도가 생길 수 있다. 

 

레퍼런스