지난 Spring Batch Job에 이어 Step에 대해 공부해보고자 한다.
Step 인터페이스

Step 클래스 구조

TaskletStep
아래는 TaskletStep을 활용한 예시이다.
Tasklet 클래스를 익명객체로 생성하였고,
멤버변수로 count를 두어 10이 되기전까지 CONTINUABLE을 반환하다가
10이 될 때 FINISHED를 반환하도록 설정하였다.

실제로 실행시켜보면 아래와 같이 로깅이 될 것이다.

이렇듯 Tasklet을 통해서 단일 실행이 아닌 여러 개의 실행을
구현할 수도 있지만, 문제는 커밋이 하나씩 일어나기 때문에
비용적인 측면에서 비효율적이다.
그래서 Spring Batch에서는 일반적으로 Chunk-oriented를 사용한다.
여기서 chunk란 작은 덩어리를 의미하는데,
데이터를 작은 덩어리 단위로 처리하여 성능과 메모리 효율성을
극대화하는 방식이다. 일반적으로 대량의 데이터를 처리할 때 주로 사용된다.
만약에 chunk 사이즈가 100이라면
100번의 read와 process가 일어난 후 한 번에 write된다.
물론 chunk-oriented 방법을 사용하면 커밋에 대한 비용은 줄일 수 있겠지만,
혹시 99번 째에서 작업을 실패하게 되면 이전의 작업 또한 모두 롤백이 되므로
이러한 부분을 주의하여 사용해야한다.

아래는 chunk-oriented processing의 예시이다.
여기서 chunkSize는 커밋 간격을 의미한다.

다음으로는 StepBuilder의 속성에 대해 설명하고자 한다.
Step Restart
allowStartIfComplete : Step이 성공해도 재시작을 허용
startLimit : Step 시작 제한 수

skip
배치 작업에서는 한 번의 실패가 Job과 Step을 멈추게 하기 때문에,
비즈니스에 따라 특정 에러를 Skip 할 수 있도록 메서드를 제공한다.

물론 메서드가 아니더라도 인터페이스의 구현을 통해서 사용할 수도 있다.

retry
특정 에러의 경우 재시도 하면 성공하는 케이스가 있기 때문에,
이러한 상황에서 사용할 수 있도록 retry 메서드를 제공한다.

skip과 마찬가지로 인터페이스를 제공하고 있고,
다양한 구현체 또한 존재하니 입맛에 맞게 사용하면 된다.

Rollback
앞에서 설명한 것과 같이 chunk 안에서 작업을 수행하다가
실패하면 rollback이 일어나기 때문에, 이런 경우에 대비하기 위해서
noRollback 메서드를 제공한다.

Interception Step
Step은 Job과는 다르게 다양한 Listener를 제공하고 있다.
상황에 맞게 적합한 Listener를 찾아서 사용하면 된다.

Conditional Flow
사실 지금까지 공부한 흐름은 Sequential Flow와 관련된 내용이고,
이외에도 Conditional Flow도 있다.
백문이 불여일견이라고 이미지를 보면 바로 이해가 될 것 이다.
첫 번째 이미지가 Sequential Flow이고,
두 번째 이미지가 Conditional Flow이다.


Flow의 속성은 아래와 같다.
나머지 속성은 이미지에 잘 설명이 되어있으니 생략하고,
Flow의 종료에 대해서만 간단히 설명하겠다.
Flow의 종료는 Completed, Failed, Stopped로 구성된다.
그리고 각각은 end(), fail(), stopAndRestart(step) 로 구현할 수 있다.

참고
해당 개념들에 대한 실습은 깃허브 페이지의 Spring Batch 프로젝트에서
확인할 수 있고, 내용에 맞는 커밋메시지를 클릭하면 관련 코드를 볼 수 있다.