본문 바로가기
Java/spring batch

[Spring Batch] #3 스프링배치 동작 방식 - 기본

by Jayson Jeong 2022. 9. 20.

개요

프로젝트를 진행하며 스프링 배치에 대해 공부한 내용 중 스프링 배치의 전반적인 동작 방식에 대해 공유하도록 하겠습니다. 이번 게시물에선 스프링 배치가 동작하는 과정을 간략하게 설명하겠습니다.

 

스프링 배치의 동작방식에 대해 알아보기전에 최소한으로 알고 있어야 하는 객체가 있습니다.

 

JobRepository

스프링 배치의 메타테이블 Repository 추상체이다. 

스프링 배치의 실행기록 및 Job과 Step의 상태 등 스프링 배치의 실행 정보들을 저장하거나 가져오는 역할을 한다.

Step의 실행 정보를 가져와 중단된 부분부터 실행할 수 있도록 한다. 그렇기 때문에 JobRepository를 사용하지 않는 

InMemory 설정을 할 경우에 중단된 부분부터 실행하는 기능을 사용할 수 없다.

일반적으로 SimpleJobRepository 구현체를 통해 구현한다.

 

Job과 JobExecution

Job은 실행할 Step들과 Listener 등 한 개의 Job을 수행하는데 필요한 모든 정보를 담고 있는 객체이다.

한 개의 Job 객체(Job안에 담긴 Step들 등)를 JobLauncher를 통해 실행하게 된다. 

일반적으로 AbstactJob과 SimpleJob을 통해 구현한다.

 

JobExecution은 실행되는 Job의 상태 정보를 담고 있는 객체로 JobInstance가 실행될 때마다 생성된다.

JobInstance

 

 

StepHandler

Job이 갖고 있는 Step의 실행을 제어하는 객체로 Transaction도 함께 제어한다.

Step 실행에 대한 전반적인 관리를 담당하며 StepExecution을 가져와 중단된 지점부터 다시 실행하도록 제어하는 역할도 한다. 

일반적으로 SimpleStepHandler 구현체를 통해 구현한다.

 

Step과 StepExecution

한 개의 Step은 한 개의 Tasklet을 갖고 있으며 RepeatStatus 결과에 따라 Tasklet을 반복 수행하게 된다. 

일반적으로 AbstractStep과 SimpleStep을 통해 구현한다. 

 

StepExecution은 실행되는 Step의 상태 정보를 나타내는 객체이다. 

Step과 StepExecution은 일 대 일 구조이다.

 

 

ExecutionContext

스프링 배치는 기본적으로 JobExecutionContext와 StepExecutionContext 두 개의 ExecutionContext를 갖고 있다. 

하지만 두 ExecutionContext는 범위가 다른데 JobExecutionContext는 Job의 실행 단위 별로, StepExecutionContext는 Step 단위로 적용된다.

 

 

알고리즘 순서도를 통한 동작 방식

먼저 알고리즘 순서도를 통해 배치의 동작방식을 간단하게 설명하겠다. 

 

JobLaunch에서 Job을 실행하고

Job이 갖고 있는 Step들을 StepHandler를 통해 순차 실행하게 된다.

StepHandler는 과거 StepExecution을 조회하여 체크하고

중단된 작업이 있을 경우 중단된 지점부터 실행, 아닐 경우 처음부터 실행하게 된다.

 

Step단으로 넘어오게 되면 Step이 갖고 있는 Tasklet 객체를 실행시키게 되는데 기본적으로 사용자가 작성한 Tasklet excute 메소드가 실행되게 된다. 

Chunk방식을 적용했을 경우 ChunkOrientedTasklet의 execute메소드가 실행되게 된다. 

 

실행 결과를 RepeatStatus로 리턴하고 기본 조건인 ResultPolicy 에 의해 RepeatStatus가 null 이면 종료, Continuble이 아니면 종료를 판단한다.

 

종료된 Step의 결과는 StepExecution에 담기고

StepExecution의 정보는 JobExecution에 담긴다.

 

Step이 모두 종료되거나 StepExecution으로부터 받은 데이터에 문제가 있을 경우 Job은 종료된다.

 

이번엔 소스 코드를 통해 동작 방식을 더욱 자세히 알아보도록 하겠다.

 

 

 

 

소스 코드를 통한 동작 방식

 

이번엔 스프링 배치의 실제 소스 코드를 통해 좀 더 자세히 알아보도록 하겠다. 

JobLauncher를 통해 Job을 실행하게 되면 Job이 갖고 있는 Step을 for문을 통해 1회씩 실행하게 된다. 

SimpleJob.java

이때 실행한 Step의 Status가 COMPLETED. 즉, 정상 종료되지 않았을 경우 배치를 종료하게 되며

StepExecution(Step의 실행 정보)을 JobExecution에 동기화를 진행하여 Job 종료시 수행결과를 JobExecution을 통해 최종적으로 확인할 수 있다.

SimpleJob.java

 

 

handlerStep(step, execution) 메소드를 통해 Step을 실행하게 되면 AbstractStep의 doExecute(stepExecution) 메소드를 실행하게 되는데, 이전 Step의 실행기록을 비교하여 중단된 부분부터 시작하는 기능도 이 단계에서 적용되며, Transaction 제어도 이 단계에서 시작하게 된다.

 

SimpleStepHandler.java
AbstractStep,java

 

AbstractStep의 doExecute(stepExecution) 메소드를 통해 step이 갖고 있는 tasklet의 execute(contribution, chunkContext) 메소드를 실행하게 된다. tasklet의 execute(contribution, chunkContext)는 원하는 배치 내용을 실행시키기 위해 구현한 Tasklet의 execute메소드이다.(우리가 구현한 내용이 실제 실행되는 부분이다)

 

추가로 Tasklet의 실행은 RepeatTemplate에서 iterate메소드를 통해 진행되며 RepeatStatus의 결과값으로 중단할지 반복할지를 결정한다. 기본값은 DefaultResultCompletionPolicy로 RepeatStatus가 null이거나 Continuable이 아닐 경우 종료이다.

 

RepeatTemplate.java
RepeatTemplate.java

 

 

 

참조. spring-batch-core:4.3.6

         spring-batch-infrastructure:4.3.6