Spring Batch Step 파헤쳐보기
Step 개념
- Batch Job 을 구성하는 독립적인 단계로 하나의 Job은 하나 이상의 Step으로 구성됩니다.
- Spring Batch Job 구현체중 하나인
SimpleJob
을 까보면 Job 은 내부 멤버변수로 Step List를 들고 있음을 확인할 수 있습니다.1
2
3
4public class SimpleJob extends AbstractJob {
private List<Step> steps = new ArrayList<>();
//...
}
StepExecution 이란?
- Step에 대한 한번의 시도를 의미하는 객체로서 Step 실행 중에 발생한 정보들을 저장하고 있는 객체입니다.
- DB의
BATCH_STEP_EXECUTION
테이블과 1:1로 매핑됩니다. - Job이 실패해서 재수행하는 경우에는 실패한 Step에 대해서만 재시작하고, 성공한 Step은 생략합니다. ( 하지만
allowStartIfComplete
설정값을 변경하면 성공한 Step도 재시작되게 변경할 수 있습니다 )
예를 들어 Step 1,2,3이 존재하는데 Step2번이 실행중에 실패한다면 Step 1은 성공 , Step 2는 실패처리 됩니다. 그리고 Step 3는 실행되지 않습니다.
이 상태에서 Job을 재시작하면 Step2부터 재시작하여 Step2,Step3 가 수행됩니다.
- Job을 구성하는 모든 Step의 실행 정보인
StepExecution
이 완료 처리되어야만JobExecution
이 완료처리됩니다.
즉 Spring Batch 도메인 용어를 정리하면 하나의 Job
은 여러개의 Step
으로 구성되고, Job이 JobParameter
를 주입받아 실행되는 객체가 JobInstance
객체입니다.
JobInstance를 실행한 정보가 JobExecution
이고, Job이 실행되면서 Job을 구성하는 Step들의 실행정보가 StepExecution
입니다.
Step간 데이터 공유하기 - ExecutionContext
ExecutionContext
를 활용하면 Job내 Step간 데이터를 공유할 수 있습니다. 혹은 실패한 Step에서 Step 재시작시 실패 이전까지 작업했던 상태값들을 가져올 수 있습니다.ExecutionContext
는 Spring Batch에서 관리하는 key-value (Map) 컬렉션입니다.StepExecution
,JobExecution
객체의 멤버변수로 선언되고 , 각각 DB의BATCH_JOB_EXECUTION_CONTEXT
,BATCH_STEP_EXECUTION_CONTEXT
테이블에 1:1 매핑됩니다.StepExecution
내ExecutionContext
는 Step안에서만 공유됩니다. 즉 특정 Step에서만 접근이 가능합니다. 실패한 Step이 재시작된 경우도 이전까지 작업한 내용을 불러들일수 있습니다.JobExeuction
내ExecutionContext
는 모든 Step안에서 공유됩니다.
예시 코드
아래와 같이 ExecutionContext
를 StepContribution
또는 ChunkContext
를 통해 접근하고, 값을 넣어줄 수 있습니다.
넣어준 값은 BATCH_JOB_EXECUTION_CONTEXT
, BATCH_STEP_EXECUTION_CONTEXT
테이블에 각각 직렬화되어 저장됩니다.
1 | public class ExecutionContextTasklet1 implements Tasklet { |
Spring Batch에서 제공하는 Step 구현체(5)
- Step 인터페이스를 AbstractStep이라는 추상 클래스에서 구현하고,AbstractStep 추상클래스를 구현하는 구조입니다.
- Batch에서 제공하는 Step의 구현체는 아래와 같은 5개의 구현체가 존재합니다.
- Tasklet Step
- Partition Step
- Job Step
- Flow Step
- Decision Step
TaskletStep
RepeatTemplate
을 사용해서 Tasklet 코드 block을 트랜잭션 경계 내(성공시 커밋,실패시 롤백)에서 반복해서 실행합니다.
언제까지 반복해서 실행할것인가에 대한 판단은 Tasklet 객체에서 반환하는RepeatStatus
값에 의해 결정됩니다.RepeatStatus.FINISHED
와 같이 특정RepeatStatus
를 반환할떄까지 계속해서 실행합니다.TaskletStep은 아래와 같은 tasklet 인터페이스를 구현하는 tasklet 구현체를 멤버변수로 가지고 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15/**
* Strategy for processing in a step.
*/
public interface Tasklet {
/**
* @return an {@link RepeatStatus} indicating whether processing is
* continuable. Returning {@code null} is interpreted as {@link RepeatStatus#FINISHED}
*
* @throws Exception thrown if error occurs during execution.
*/
RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception;
}TaskletStep의 코드를 확인해보면 Tasklet 호출횟수를 조정하기 위한 RepeatTemplate 와 실행되야할 작업 그 자체 (tasklet) 구현체를 멤버변수로 들고있는것을 확인할 수 있습니다.
1 | public class TaskletStep extends AbstractStep { |
- 자주 사용되는 tasklet 구현체는 Spring Batch에서 이미 구현해놓았습니다. 이 중
ChunkOrientedTasklet
구현체을 활용해 Chunk 단위로 배치 작업을 쪼개서 처리할 수 있습니다.