Spring Batch
Job·Step·Tasklet·Chunk 같은 구성요소가 실제로 어떻게 맞물려 도는지, 그리고 BATCH_JOB_INSTANCE 등 메타 테이블이 재시작·중복 실행 방지를 어떻게 보장하는지.
Spring Batch
Spring Batch가 필요한 경우
- 작업이 여러 단계로 구성된 복잡한 흐름을 가질 때 (예: 읽기 -> 처리 -> 쓰기).
- 작업이 대량 데이터를 트랜잭션 관리와 함께 처리해야 할 때.
- 실패 재시도(retry), 재시작(resume) 등의 기능이 필요한 경우.
- 작업 실행 이력을 저장하고 이를 기반으로 분석이나 관리가 필요할 때.
구성요소
- Job: 배치 작업의 실행 단위. 여러 Step으로 구성됨.
- Step: 배치 작업의 단계. ItemReader, ItemProcessor, ItemWriter로 구성됨.
- JobRepository: Job과 Step의 실행 상태를 관리하는 저장소.
- JobLauncher: Job을 실행하는 인터페이스.
- JobInstance: Job의 실행 단위. JobParameters로 구분됨. (JobParameter가 동일하면 같은 JobInstance로 간주)
- JobExecution: Job의 실행 상태. JobInstance와 JobParameters를 가짐. (각 실행마다 새로운 JobExecution이 생성됨)
- Tasklet: Step의 실행 단위. Step의 실행을 담당하는 인터페이스.
Tasklet vs Chunk Tasklet은 데이터 처리 과정이 단일 작업으로 이루어질 때 사용하며, Chunk는 데이터 처리 과정이 여러 작업으로 이루어질 때 사용한다. Tasklet은 Step의 실행을 담당하는 인터페이스이며, Chunk는 Tasklet을 구현한 것으로, Chunk는 Tasklet을 상속받아 구현된 것이다.
- ItemReader: Step에서 사용되는 Item을 읽어오는 인터페이스.
- ItemProcessor: Step에서 사용되는 Item을 가공하는 인터페이스.
- ItemWriter: Step에서 사용되는 Item을 저장하는 인터페이스.
Job 관련 인터페이스
- JobParameters: Job을 실행할 때 전달되는 파라미터를 저장하는 객체.
- JobRegistry: Job을 등록하고 관리하는 인터페이스. (Job을 등록하고, Job을 실행할 때 사용)
- JobExplorer: JobExecution과 JobInstance를 조회하는 인터페이스.
배치 생성 절차
- Job을 생성한다.
- Job에 Step을 추가한다.
- Step에 ItemReader, ItemProcessor, ItemWriter를 설정한다.
- Job을 실행한다.
Batch Meta Tables
- BATCH_JOB_INSTANCE
- JobInstance의 정보를 저장하는 테이블.
- 배치가 수행되면 Job이 생성이 되고, 해당 잡 인스턴스에 대해서 관련된 모든 정보를 가진 최상위 테이블.
- JobInstance는 JobParameters를 가지고 있으며, JobParameters가 동일하면 같은 JobInstance로 간주한다.
- JobInstance가 한번 실행되고 완료되면, 기존의 JobInstance를 다시 실행할 수 없다. (중복 실행 방지)
- BATCH_JOB_EXECUTION
- JobExecution의 정보를 저장하는 테이블.
- Job이 매번 실행될때, JobExecution이라는 새로운 객체가 생성되고, 해당 객체에 대한 정보를 저장하는 테이블.
- BATCH_JOB_EXECUTION_PARAMS
- JobParameters의 정보를 저장하는 테이블.
- JobParameters는 Job을 실행할 때 전달되는 파라미터를 저장하는 객체.
- BATCH_JOB_EXECUTION_CONTEXT
- JobExecutionContext의 정보를 저장하는 테이블.
- JobExecutionContext는 Job이 실행될 때, JobExecution과 함께 생성되는 객체로, 해당 객체에 대한 정보를 저장하는 테이블.
- 실패 후 중단된 부분부터 시작될 수 있도록 실패후 검색해야하는 상태를 나타낸다.
- BATCH_STEP_EXECUTION
- StepExecution의 정보를 저장하는 테이블.
- Step이 실행될 때, StepExecution이라는 새로운 객체가 생성되고, 해당 객체에 대한 정보를 저장하는 테이블.
- BATCH_STEP_EXECUTION_CONTEXT
- StepExecutionContext의 정보를 저장하는 테이블.
- StepExecutionContext는 Step이 실행될 때, StepExecution과 함께 생성되는 객체로, 해당 객체에 대한 정보를 저장하는 테이블.
- 실패 후 중단된 부분부터 시작될 수 있도록 실패후 검색해야하는 상태를 나타낸다.
재시작·중복 실행 방지 메커니즘
메타 테이블을 나열하는 것만으로는 “이게 왜 필요한가”가 안 잡힌다. 핵심은 JobParameters가 JobInstance의 신원(identity)을 결정한다는 것이다.
중복 실행 방지
- 같은 Job을 같은 JobParameters로 다시 실행하면, Spring Batch는
BATCH_JOB_INSTANCE에서 동일 인스턴스를 찾는다. 그 인스턴스가 이미
COMPLETED면 재실행을 거부한다:1 2
JobInstanceAlreadyCompleteException: A job instance already exists and is complete for parameters={date=2024-11-28}- 그래서 매일 도는 배치는 날짜 같은 유니크 파라미터를 넣어 매번 새 JobInstance를 만든다. 파라미터가 늘 같으면 두 번째 실행부터 막힌다.
- 스케줄러로 계속 돌려야 하는데 마땅한 유니크 값이 없으면
RunIdIncrementer를 써서run.id를 자동 증가시킨다.
Spring Batch 4+는 파라미터를 identifying / non-identifying으로 구분한다. non-identifying(
identifying=false) 파라미터는 JobInstance 신원 계산에서 빠지므로, 신원에 영향 없이 실행별 값(예: 로그용 타임스탬프)을 넘길 수 있다.
재시작(resume)
FAILED나STOPPED로 끝난 JobExecution은 같은 파라미터로 다시 실행하면 이어서 돈다(중복 방지 규칙의 예외).- 어디서부터 이어갈지는
BATCH_STEP_EXECUTION_CONTEXT/BATCH_JOB_EXECUTION_CONTEXT에 저장된 상태로 결정된다. Chunk 모델이면 커밋된 지점까지의 read/write count가 여기 남아, 이미 처리한 청크는 건너뛰고 실패 지점부터 재개한다. - 완료된 Step은 기본적으로 재실행 시 건너뛴다(
allowStartIfComplete(true)로 강제 가능). - 재시작을 원치 않는 Job은
preventRestart()로 막을 수 있다.
Spring Batch의 실행 흐름
처리흐름 관점
- JobScheduler 가 배치를 트리거링 하면 JobLauncher 를 실행한다.
- JobLauncher 는 Job을 실행한다. 이때 JobExecution 을 수행하고, Execution Context 정보를 이용한다.
- Job은 자신에게 정으된 Step을 실행한다. 이때 StepExecution을 수행하고, Execution Context 정보가 전달되어 수행된다.
- Step은 Tasklet과 Chunk모델을 가지고 있으며 위 그림에서는 Chunk 모델로 수행되게 된다.
- Chunk 모델은 ItemReader를 통해서 소스 데이터를 읽어 들인다.
- ItemProcessor를 통해서 읽어들인 청크단위 데이터를 처리한다. 처리는 데이터를 변환하거나 가공하는 역할을 하게 된다.
- ItemWriter는 처리된 청크 데이터를 쓰기작업한다. 다양한 Writer를 통해 데이터베이스에 저장하거나, 파일로 쓰는 역할을 하게 된다.
출처 & 참고
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.

