이 페이지에서
1. JobRepository 개요
Spring Batch는 엔터프라이즈급 배치 처리를 위한 강력하고 유연한 프레임워크입니다.
배치 작업의 실행 정보를 효과적으로 관리하고 추적하는 것은 매우 중요한데, 이를 위해 Spring Batch에서는 JobRepository를 제 공합니다.
JobRepository는 배치 작업의 실행에 관한 모든 정보를 저장하고 관리하는 핵심 구성 요소입니다.
1.1 JobRepository의 필요성
데몬처럼 끝없이 실행되는 작업이 아닌 언젠가 종료되는 처리를 UI 없이 독립 실행형으로 동작하도록 개발하는 것은 어렵지 않습니다.
CommandLineRunner를 사용하여 비즈니스 로직이 포함된 단일 기능을 실행한 뒤 종료되는 스프링 부트 애플리케이션을 만들 수 있습니다.
이정도 작업에는 스프링 배치가 필요하지 않습니다.
그러나 문제는 진행 중인 작업의 상태를 추적하고, 실패한 작업을 재시작하며, 작업 실행 이력을 관리하는 것입니다.
엔터프라이즈 환경에서는 매우 중요한 요구사항입니다.
잡의 상태 관리 기능은 스프링 배치가 제공하는 주요 기능 중 하나입니다.
잡의 상태는 JobRepository에 저장되며, 이를 통해 배치 작업의 실행 이력을 관리할 수 있습니다.
1.2 JobRepository의 의미
스프링 배치에서 JobRepository는 두 가지 의미를 가집니다.
JobRepository 인터페이스: 배치 작업의 실행 정보를 저장하고 관리하는 역할을 정의합니다.
JobRepository 구현체: JobRepository 인터페이스를 구현한 클래스는 실제로 데이터베이스에 작업 실행 정보를 저장하고 조회하는 기능을 제공합니다.
개발자는 JobRepository 인터페이스를 직접 다루는 일이 거의 없으므로 구현체에 집중하게 됩니다.
1.3 관계형 데이터베이스 지원
JobRepository는 일반적으로 관계형 데이터베이스에 작업 실행 정보를 저장합니다.
스프링 배치가 제공하는 여러 데이터베이스 테이블을 사용해 배치 메타데이터를 저장합니다.
2. JobRepository의 역할
2.1 주요 기능
Job 및 Step 실행 정보 저장
JobRepository는 JobExecution, StepExecution 등의 객체를 생성하고 관련 정보를 데이터베이스에 저장합니다.
이를 통해 배치 작업의 실행 상태, 시작/종료 시간, 처리한 레코드 수 등을 추적할 수 있습니다.
ExecutionContext 관리
ExecutionContext는 Job이나 Step의 실행 중 상태 정보를 저장하는 데 사용됩니다.
JobRepository는 이러한 ExecutionContext를 데이터베이스에 저장하고 필요할 때 조회할 수 있도록 합니다.
재시작 지원
JobRepository에 저장된 실행 정보를 바탕으로 실패한 배치 작업을 재시작할 수 있습니다.
이때 이전 실행에서 성공한 Step은 건너뛰고, 실패한 Step부터 다시 시작할 수 있습니다.
3. 메타데이터 스키마 구조
3.1 도메인 객체와 테이블 매핑
Spring Batch의 메타데이터 테이블은 Java 도메인 객체와 밀접하게 매핑됩니다.
예를 들어, JobInstance, JobExecution, JobParameters, StepExecution은 각각 BATCH_JOB_INSTANCE, BATCH_JOB_EXECUTION,
BATCH_JOB_EXECUTION_PARAMS, BATCH_STEP_EXECUTION 테이블에 매핑됩니다.
ExecutionContext는 BATCH_JOB_EXECUTION_CONTEXT와 BATCH_STEP_EXECUTION_CONTEXT 테이블 모두에 매핑됩니다.
JobRepository는 각 Java 객체를 올바른 테이블에 저장하고 관리하는 역할을 담당합니다.
3.2 DDL 스크립트
Spring Batch 코어 JAR 파일에는 여러 데이터베이스 플랫폼에 대한 관계형 테이블 생성을 위한 스크립트 예제가 포함되어 있습니다.
이들 스크립트는 추가 인덱스 및 제약조건을 원하는 대로 수정하여 사용할 수 있습니다.
파일 이름은 schema-*.sql
형태이며, *
은 목표 데이터베이스 플랫폼의 약칭입니다.
스크립트는 org.springframework.batch.core 패키지에 있습니다.
3.3 버전 컬럼과 낙관적 잠금
Spring Batch는 데이터베이스 업데이트 시 낙관적 잠금(optimistic locking) 전략을 사용합니다.
레코드가 업데이트될 때마다 버전 컬럼의 값이 1씩 증가하며, 저장 시점에 버전 번호가 변경되었다면 OptimisticLockingFailureException이 발생합니다.
3.4 식별자 생성
BATCH_JOB_INSTANCE, BATCH_JOB_EXECUTION, BATCH_STEP_EXECUTION 테이블에는 각각 _ID
로 끝나는 기본 키 컬럼이 있습니다.
이 값은 데이터베이스에서 자동 생성되는 것이 아니라 별도의 시퀀스를 통해 생성됩니다.
많은 데이터베이스 벤더가 시퀀스를 지원하지 않는 경우, MySQL의 경우처럼 테이블을 사용하여 시퀀스를 대체할 수 있습니다.
4. JobRepository의 핵심 구성 요소
4.1 JobInstance
배치 Job의 논리적 실행 단위로, Job의 이름과 JobParameters의 조합으로 식별됩니다.
동일한 JobInstance에 대해 여러 번의 JobExecution이 존재할 수 있습니다.
4.2 JobExecution
Job의 물리적 실행 단위로, 특정 시점에 실행된 Job의 상태 정보를 나타냅니다.
JobInstance와 생성 시간으로 식별되며, 시작/종료 시간, 상태, ExitStatus 등의 정보를 포함합니다.
4.3 StepExecution
Step의 물리적 실행 단위로, 특정 JobExecution 내에서 실행된 Step의 상태 정보를 나타냅니다.
StepExecution은 JobExecution과 Step 이름으로 식별되며, 시작/종료 시간, 상태, commit count, rollback count 등의 정보를 포함합니다.
4.4 ExecutionContext
Job 또는 Step 실행 중 필요한 상태 정보를 저장하는 Key-Value 형태의 데이 터 구조입니다.
JobExecution과 StepExecution은 각각 고유한 ExecutionContext를 가지고 있어, 실행 중 상태를 유지하고 재시작 시 이를 활용할 수 있습니다.
5. 주요 메타데이터 테이블
5.1 BATCH_JOB_INSTANCE
JobInstance에 대한 모든 정보를 저장하고 전체 계층 구조의 최상위에 위치합니다.
고유 정보가 포함된 잡 파라미터로 잡을 처음 실행하면 단일 JobInstance 레코드가 테이블에 생성됩니다.
테이블 필드
JOB_INSTANCE_ID: JobInstance의 고유 식별자입니다.
VERSION: 낙관적 잠금을 위한 버전 번호입니다.
JOB_NAME: Job의 이름입니다.
JOB_KEY: Job의 이름과 JobParameters를 기반으로 생성된 JobInstance의 고유 키입니다.(해시 값)
5.2 BATCH_JOB_EXECUTION_PARAMS
JobParameters 객체에 대한 모든 정보를 저장하며, Job에 전달된 0개 이상의 키/값 쌍을 포함합니다.
이 테이블에는 잡이 매번 실행될 때마다 사용된 잡 파라미터를 저장합니다.
테이블 필드
JOB_EXECUTION_ID: JobExecution의 고유 식별자입니다.
TYPE_CODE: 파라미터의 타입을 나타내는 문자열 코드입니다.
KEY_NAME: 파라미터의 키 이름입니다.
STRING_VAL: 문자열 타입 파라미터의 값입니다.
DATE_VAL: 날짜 타입 파라미터의 값입니다.
LONG_VAL: 숫자 타입 파라미터의 값입니다.
DOUBLE_VAL: 실수 타입 파라미터의 값입니다.
IDENTIFYING: 파라미터가 JobInstance를 식별하는 데 사용되는지 여부를 나타내는 플래그입니다.
5.3 BATCH_JOB_EXECUTION
JobExecution 객체에 대한 모든 정보를 저장하며, Job이 실행될 때마다 새로운 JobExecution과 이 테이블의 새 행이 생성됩니다.
잡이 실행되는 동안 주기적으로 업데이트되며, 잡이 완료되면 최종 상태가 저장됩니다.
테이블 필드
JOB_EXECUTION_ID: JobExecution의 고유 식별자입니다.
VERSION: 낙관적 잠금을 위한 버전 번호입니다.
JOB_INSTANCE_ID: JobInstance의 고유 식별자입니다.
CREATE_TIME: JobExecution이 생성된 시간입니다.
START_TIME: JobExecution이 시작된 시간입니다.
END_TIME: JobExecution이 종료된 시간입니다.
STATUS: JobExecution의 현재 상태입니다.
EXIT_CODE: JobExecution의 종료 코드입니다.
EXIT_MESSAGE: EXIT_CODE와 관련된 메시지나 스택 트레이스입니다.
LAST_UPDATED: JobExecution이 마지막으로 업데이트된 시간입니다.
5.4 BATCH_STEP_EXECUTION
StepExecution 객체에 대한 모든 정보를 저장하며, 각 JobExecution에 대해 Step별로 최소 하나의 항목이 존재합니다.
테이블 필드
STEP_EXECUTION_ID: StepExecution의 고유 식별자입니다.
VERSION: 낙관적 잠금을 위한 버전 번호입니다.
STEP_NAME: Step의 이름입니다.
JOB_EXECUTION_ID: JobExecution의 고유 식별자입니다.
START_TIME: StepExecution이 시작된 시간입니다.
END_TIME: StepExecution이 종료된 시간입니다.
STATUS: StepExecution의 현재 상태입니다.
COMMIT_COUNT: 커밋된 트랜잭션 수입니다.
READ_COUNT: 읽은 레코드 수입니다.
FILTER_COUNT: 필터링된 레코드 수입니다.
WRITE_COUNT: 쓴 레코드 수입니다.
READ_SKIP_COUNT: 읽기에서 건너뛴 레코드 수입니다.
WRITE_SKIP_COUNT: 쓰기에서 건너뛴 레코드 수입니다.
PROCESS_SKIP_COUNT: 처리에서 건너뛴 레코드 수입니다.
ROLLBACK_COUNT: 롤백된 트랜잭션 수입니다.
EXIT_CODE: StepExecution의 종료 코드입니다.
EXIT_MESSAGE: StepExecution의 종료 메시지입니다.
LAST_UPDATED: StepExecution이 마지막으로 업데이트된 시간입니다.
5.5 BATCH_JOB_EXECUTION_CONTEXT
Job의 ExecutionContext에 대한 모든 정보를 저장하며, 각 JobExecution에 대해 정확히 하나의 Job ExecutionContext가 존재합니다.
테이블 필드
JOB_EXECUTION_ID: JobExecution의 고유 식별자입니다.
SERIALIZED_CONTEXT: ExecutionContext의 직렬화된 값입니다.
SHORT_CONTEXT: 트림 처리된 SERIALIZED_CONTEXT입니다.
5.6 BATCH_STEP_EXECUTION_CONTEXT
Step의 ExecutionContext에 대한 모든 정보를 저장하며, 각 StepExecution에 대해 정확히 하나의 ExecutionContext가 존재합니다.
테이블 필드