Spring Batch skip 로직 동작 방식

Spring Batch에는 skip-limit라는 설정을 할 수 있습니다.

chunk 단위 처리할 때 skip-limit에 설정된 횟수만큼은 예외가 발생해도 예외를 skip하고 계속해서 잡이 수행됩니다.

이 정도만 알고 있었는데 skip-limit를 실제 적용해보면서 새롭게 알게된 것들이 있어 정리해봅니다.

아래와 같이 chunk 설정을 해서 1개 단위로 처리를 하고 발생하는 예외에 대해서 7번까지 skip하고 진행하고자 했습니다.

<chunk reader="itemReader" processor="itemProcessor" writer="itemWriter" 
        commit-interval="1" skip-limit="7">
 <skippable-exception-classes>
 <include class="java.lang.Exception"/>
 </skippable-exception-classes>
</chunk>

설정이 잘 동작하는지 테스트를 해보니 processor에서 예외가 발생한 경우 예외가 발생한 item은 skip되고 다음 item 처리로 넘어갔습니다.

하지만 writer에서 예외가 발생한 경우는 skip되지 않고 같은 item이 다시 processor부터 다시 처리되었습니다. 정확히는 한 번 재처리되었습니다.

왜 바로 skip되지 않고 한번 재처리 한 후에 skip되는지 알 수가 없어 검색을 해보니 다음과 같은 내용 때문에 그렇게 동작하는 것이었습니다.

reader, processor는 동작 시에 item 하나씩 처리하지만 writer는 reader, processor에서 처리된 item을 commit-interval 설정 값만큼 list로 받아서 처리합니다.

reader, processor는 처리 중이었던 item을 skip하면 됩니다. writer 처리 로직에서도 예외가 발생하면 예외가 발생한 item만 skip해야하는데

list의 item 중 어떤 것을 처리하다가 발생했는지 Spring Batch로써는 알 수가 없습니다.

그래서 Spring Batch는 예외가 발생했던 list의 item 하나씩 processor, writer를 다시 수행합니다. 이렇게 하기 위해서 commit-interval을 일시적으로 1로 변경합니다.

재수행하면서 에러가 발생했던 item은 에러가 발생할 것이고 에러가 발생하지 않은 item은 성공할 때마다 커밋이 발생합니다. 그리고 재수행 시 에러가 발생할 때 실제로 skip count가 증가하게 됩니다.

(하지만 재수행 시 에러가 재발하지 않을 수도 있기 때문에 skip되는 item이 없을 수 있습니다.)

에러난 item들의 재처리가 끝나고 난 뒤에는 commit-interval 값은 원래 설정대로 되돌아 갑니다.

저는 위 설정에서 commit-interval을 1로 지정했었고 이런 이유로 예외가 발생할 때 마다 처리 중이던 1개의 item이 다시 processor부터 재수행되는 것이었습니다.

위 내용이 표현된 그림이 있습니다.

출처 : https://blog.codecentric.de/files/2012/03/Blog_Transactions_SkipInWrite-1024x512.png


writer에서 에러가 발생했으면 writer만 재수행하면 되는데 굳이 processor부터 재수행하는 이유는,

processor에도 DB 작업이 있을 수 있기 때문입니다. writer에서 에러가 발생하면 트랜잭션이 롤백되기 때문에 processor에서 수행했던 DB 작업들도 롤백됩니다.

그래서 재수행할 경우 다시 processor부터 재수행하는 것입니다. 하지만 processor에서 DB 작업이 없다면 굳이 processor부터 재수행할 필요는 없기 때문에

processor-transactional="true" 설정을 추가하면 writer부터 재수행하게 할 수 있습니다.

(설정을 추가하면 processor 결과를 캐싱해두고 그것을 이용해서 writer부터 다시 시작합니다.)

이런식으로 재수행되면 DB 작업은 롤백되기 때문에 기존에 했던 작업은 취소되지만 DB 작업 이외의 작업들은 같은 작업이 두 번 수행될 수 있다는 점을 유의해야 할 것 같습니다.


참고 자료