Spring Batch 입문 5편. Batch Infrastructure 설정 — @EnableBatchProcessing 의 모든 것, JobRepository·JobOperator·TransactionManager 자동 생성, ResourcelessJobRepository (v6 신규), DefaultBatchConfiguration·JdbcDefaultBatchConfiguration·MongoDefaultBatchConfiguration 비교까지 풀어쓴 학습 노트.
이 글은 Spring Batch 입문에서 운영까지 시리즈 48편 중 5편이에요. 4편 까지 Part 1 입문 을 끝냈다면, 이번 5편부터 Part 2 — Job 설정·실행 (6편) 으로 들어가요. 첫 글은 모든 Job 의 기반 — Batch Infrastructure (배치 실행을 떠받치는 하부 구조).
Batch Infrastructure가 어렵게 느껴지는 이유
Spring Batch 가 자동으로 만들어주는 bean 들이 어떤 게 만들어지는지·어떻게 customize 하는지 가 모호하다는 것.
첫째, @EnableBatchProcessing(배치 자동 구성 활성 어노테이션)의 의미. 어노테이션 한 줄이 수많은 bean 을 자동으로 만들어내는데, 정확히 어떤 bean 이고 default 값은 무엇인지가 잘 안 보여요.
둘째, v6 의 ResourcelessJobRepository(DB 없이 메모리만 쓰는 JobRepository). 학습·테스트엔 편한데, 언제 쓰고 언제 안 쓰는지가 헷갈려요.
셋째, DefaultBatchConfiguration vs annotation. 두 방식이 같은 결과를 내는데, 그럼 언제 어느 쪽을 골라야 하는지.
이 글에서 infrastructure bean 6가지 + 3가지 설정 방식 + 운영 권장까지.
Infrastructure Beans 6가지
Spring Batch 가 만드는 핵심 bean:
1. JobRepository
public interface JobRepository {
void add(JobExecution jobExecution);
void update(JobExecution jobExecution);
JobExecution createJobExecution(Job job, JobParameters parameters);
// ...
}
JobRepository(Job/Step 실행 상태를 저장하는 저장소)는 모든 Job/Step 실행 상태를 영속 저장해요. 7편에서 깊이 다뤄요.
2. JobOperator
public interface JobOperator {
Long start(Job job, JobParameters parameters);
boolean stop(long executionId);
Long restart(long executionId);
// ...
}
JobOperator(Job 실행·중지·재시작 진입점)가 Job 의 시작·중지·재시작을 책임져요. 8편 깊이.
3. TransactionManager
PlatformTransactionManager(스프링 트랜잭션 추상화). chunk 단위 transaction commit/rollback 의 기반이에요.
4. JobLauncher (자주 JobOperator 가 wrap)
JobLauncher(실제 Job 을 시작시키는 컴포넌트)가 Job 을 실제로 띄워요.
5. JobRegistry (옵션)
JobRegistry(이름으로 Job 을 찾기 위한 레지스트리)는 이름 → Job 매핑을 들고 있어요. CLI·REST 에서 이름으로 호출할 때 필요해요.
6. JobScope·StepScope
@Bean
@StepScope
public ItemReader<String> reader(@Value("#{jobParameters['filePath']}") String filePath) {
// ...
}
JobScope·StepScope(Job·Step 생명주기에 묶인 bean scope). late binding (실행 시점에 값 주입) 으로 동작해요 — 21편에서 다뤄요.
v6 — 3가지 설정 방식
Way 1: @EnableBatchProcessing (기본 — Resourceless)
@Configuration
@EnableBatchProcessing
public class MyJobConfig {
@Bean
public Job job(JobRepository repo) {
return new JobBuilder("myJob", repo).build();
}
}
v6 의 기본 동작은 ResourcelessJobRepository 예요. 메모리 only, DB 안 필요.
장점:
- 학습·테스트 매우 간단
- DB·schema 설정 없이 시작
단점:
- Job 재시작 불가 (메모리만 → 종료 시 사라짐)
- 운영 환경 절대 사용 X
Way 2: @EnableJdbcJobRepository (운영 표준)
@Configuration
@EnableBatchProcessing
@EnableJdbcJobRepository
public class MyJobConfig {
// DataSource 필요 (Spring Boot 자동)
}
@EnableJdbcJobRepository(JDBC 기반 JobRepository 활성). DB 에 영속 저장, 재시작 가능. 운영 환경 권장.
자동 활성 조건 (Spring Boot):
spring-boot-starter-data-jpa또는spring-jdbc의존성DataSourcebean 존재
Way 3: @EnableMongoJobRepository
@EnableMongoJobRepository
MongoDB 기반. RDBMS 안 쓰는 환경 의 옵션이에요. v6 신규.
DefaultBatchConfiguration — Class 기반
annotation 대신 class 상속:
@Configuration
public class MyBatchConfig extends DefaultBatchConfiguration {
@Bean
public Job job(JobRepository repo) {
// ...
}
}
DefaultBatchConfiguration(상속으로 배치 설정을 커스터마이즈하는 베이스 클래스)에 세 갈래가 있어요:
DefaultBatchConfiguration— ResourcelessJdbcDefaultBatchConfiguration— JDBCMongoDefaultBatchConfiguration— MongoDB
annotation vs class 차이:
- annotation = 더 짧고 간결
- class = override 자유 (특정 bean customize 시)
대부분 환경은 annotation 으로 충분해요.
Spring Boot 자동 구성
Spring Boot 의 BatchAutoConfiguration(Spring Boot 가 배치 컴포넌트를 자동 등록하는 자동 구성)이 대부분 자동 처리:
@SpringBootApplication
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}
이거면 끝. Spring Boot 가 알아서:
JobRepository자동 생성 (DataSource 있으면 JDBC, 없으면 Resourceless)JobOperator·JobLauncher·TransactionManager자동- DB schema 자동 초기화 (
spring.batch.jdbc.initialize-schema=always) - Job 자동 실행 (
spring.batch.job.enabled=true)
여기서 시험 함정이 하나 있어요 — Spring Boot 가 @EnableBatchProcessing 자동 추가 X. 명시 해야 해요. (v5 부터)
@Configuration
@EnableBatchProcessing // 명시!
public class BatchConfig { }
운영 환경 권장 설정
application.yml
spring:
datasource:
url: jdbc:postgresql://db:5432/batch
username: ${DB_USER}
password: ${DB_PASSWORD}
hikari:
maximum-pool-size: 10
minimum-idle: 2
batch:
jdbc:
initialize-schema: never # 운영 환경 = never
schema: classpath:org/springframework/batch/core/schema-postgresql.sql
table-prefix: BATCH_
job:
enabled: false # CLI 또는 REST 로 명시 실행
핵심:
initialize-schema: never= 운영에서 자동 schema 는 위험해요. DBA 가 수동 적용.spring.batch.job.enabled: false= application 시작 시 자동 실행 X.JobLauncher로 명시 실행.
명시 schema 생성 (운영 첫 deploy)
$ psql -d batch < schema-postgresql.sql
schema 파일은 spring-batch-core jar 안에 들어 있어요. 47편 Schema 에서 더 깊이 다뤄요.
명시 Job 실행
CLI:
$ java -jar my-batch.jar --job.name=myJob --param1=value1
또는 REST:
@RestController
public class JobController {
@Autowired
private JobOperator jobOperator;
@PostMapping("/jobs/{name}/start")
public Long start(@PathVariable String name, @RequestBody Map<String, String> params) {
Job job = jobRegistry.getJob(name);
return jobOperator.start(job, buildParameters(params));
}
}
Customizing — DefaultBatchConfiguration override
특정 bean override:
@Configuration
public class CustomBatchConfig extends JdbcDefaultBatchConfiguration {
@Override
protected String getTablePrefix() {
return "MY_BATCH_"; // 기본 "BATCH_" → "MY_BATCH_"
}
@Override
protected Charset getCharset() {
return StandardCharsets.UTF_8;
}
@Override
protected DatabaseType getDatabaseType() {
return DatabaseType.POSTGRES;
}
// 기타 customize ...
}
자주 customize 하는 자리:
getTablePrefix()— 여러 batch 가 같은 DB schema 를 공유할 때 분리용getCharset()— 비-UTF-8 환경getMaxVarCharLength()— long parameter·context 저장getDatabaseType()— auto-detect 안 될 때
Table Prefix — 다중 Batch
같은 DB 에 여러 batch application 이 공유될 때:
# Batch A
spring.batch.jdbc.table-prefix: BATCH_A_
# Batch B
spring.batch.jdbc.table-prefix: BATCH_B_
각자 별도로 BATCH_A_*·BATCH_B_* 테이블을 써요. 충돌 없음.
Multi DataSource — Business 와 Batch 분리
큰 운영 환경에서 자주 보이는 패턴 — business 데이터 DB 와 JobRepository DB 분리.
@Configuration
public class BatchConfig extends JdbcDefaultBatchConfiguration {
@Bean
@ConfigurationProperties("spring.datasource.batch")
public DataSource batchDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@Primary
@ConfigurationProperties("spring.datasource.business")
public DataSource businessDataSource() {
return DataSourceBuilder.create().build();
}
@Override
@Bean
public DataSource getDataSource() {
return batchDataSource();
}
@Override
@Bean
public PlatformTransactionManager getTransactionManager() {
return new JdbcTransactionManager(batchDataSource());
}
}
spring:
datasource:
batch:
url: jdbc:postgresql://batch-db:5432/batch_meta
business:
url: jdbc:postgresql://biz-db:5432/business
장점은 batch 메타데이터 DB 가 business DB 영향 X. 백업·복구도 따로 분리돼요.
Bean 의존성 한눈에
DataSource (Spring Boot 자동)
↓
TransactionManager (JdbcTransactionManager)
↓
JobRepository (JdbcJobRepository) ──┐
↓ │
JobLauncher ↓
↓ JobOperator
[Job] ↔ [Step] ↔ [Reader/Writer]
대부분 자동이라 직접 만들 일은 거의 없어요.
모니터링·디버깅
로그
logging:
level:
org.springframework.batch.core: INFO
org.springframework.batch.repeat: DEBUG # chunk 단위 디버깅
org.springframework.transaction: DEBUG # transaction 추적
Actuator
management:
endpoints:
web:
exposure:
include: health,info,batch
endpoint:
batch:
enabled: true
/actuator/batch 가 현재 Job 상태 를 노출해요 (Spring Boot 3.5+).
한계·실무 함정
1. ResourcelessJobRepository 운영 사용
절대 X. 재시작 불가에 이력이 사라져서 운영 사고로 직결돼요.
2. initialize-schema: always 운영
운영 DB 가 부팅마다 schema 재생성 을 시도해요. 위험.
3. job.enabled: true 운영
운영 환경에서 부팅마다 Job 이 자동 실행 돼서 의도 안 한 실행이 일어나요. 명시 실행 권장.
4. @EnableBatchProcessing 누락
Spring Batch 6 부터는 명시 필수. 누락하면 Bean 이 만들어지지 않아요.
5. Table prefix 통일
여러 application 이 같은 prefix 를 쓰면 transaction 안에서 메타데이터가 충돌 해요. 명시 분리.
6. Multi-DataSource transaction 분리
batch metadata 와 business data 가 다른 DB 인데 같은 transaction 으로 처리하려고 하면 2-phase commit 필요 (XA, 두 DB 를 한 트랜잭션으로 묶는 분산 커밋 프로토콜). 분리 권장.
시험 직전 한 번 더 — Batch Infrastructure 함정 압축 노트
- Infrastructure Beans 6가지 = JobRepository · JobOperator · TransactionManager · JobLauncher · JobRegistry · JobScope/StepScope
- 3가지 설정 방식 =
@EnableBatchProcessing(기본, Resourceless) ·@EnableJdbcJobRepository(운영) ·@EnableMongoJobRepository - 또는 class —
DefaultBatchConfiguration·JdbcDefaultBatchConfiguration·MongoDefaultBatchConfiguration - ResourcelessJobRepository (v6 신규) = 메모리 only, 학습·테스트만
- 운영 표준 =
@EnableJdbcJobRepository(또는 Mongo) - Spring Boot = 대부분 자동 (DataSource 있으면 JDBC), 단
@EnableBatchProcessing명시 필요 - 운영 yml —
initialize-schema: never+job.enabled: false - 명시 schema = jar 안
schema-<db>.sql을 DBA 가 적용 - 명시 Job 실행 = CLI·REST·
JobOperator.start() - DefaultBatchConfiguration override —
getTablePrefix·getCharset·getMaxVarCharLength·getDatabaseType - Table Prefix = 다중 batch application 분리 (
BATCH_A_·BATCH_B_) - Multi-DataSource = batch metadata DB ↔ business DB 분리 (운영 권장)
- Bean 의존성 —
DataSource → TransactionManager → JobRepository → JobLauncher/Operator - 로그 —
org.springframework.batch.core: INFO·repeat: DEBUG /actuator/batch(Spring Boot 3.5+)- 함정 — Resourceless 운영 사용 = 재시작 불가
- 함정 —
initialize-schema: always운영 = DB schema 위험 - 함정 —
job.enabled: true운영 = 부팅마다 자동 실행 - 함정 —
@EnableBatchProcessing누락 (v6 명시 필수) - 함정 — Table prefix 통일 = 메타데이터 충돌
- 함정 — Multi-DataSource 의 transaction = 2PC 필요
공식 문서: Batch infrastructure Configuration 에서 원문을 확인할 수 있어요.
시리즈 다른 편 (앞뒤 글 모음)
이전 글:
- 1편 — Spring Batch란 + 언제 쓰는가
- 2편 — Architecture (Application · Core · Infrastructure)
- 3편 — Domain Language (Job · JobInstance · Step · Item · Chunk)
- 4편 — v6 What's New + Hello Job 5분 hands-on
다음 글: