Spring batch Chunk 처리시 주의할점! (데이터 무결성 깨짐)

Minsu Kang·2021년 12월 14일
1

얼마전 스프링 배치를 이용해 청크단위로 데이터를 처리하다가 데이터를 read 하지 못하는 문제가 발생했다. 간략한 시나리오는 아래와 같다.

현재 상황

  • status 컬럼의 값이 ENABLED 인 데이터를 가져와서 DISABLED 상태로 바꿔야함
  • chunkSize = 5
  • 현재 DB 에는 status == ENABLED 인 데이터가 10개 존재

배치 실행
1. reader 에서 status == ENABLED 인 데이터 조회 (limit 0,5)
2. processor, writer 에서 status = DISABLED 로 변경하여 저장
3. reader 에서 status == ENABLED 인 데이터 조회 (limit 5, 5)
4. 5번째 ~ 10번째 데이터를 처리할거라고 예상했으나 read 하지 못하고 배치 종료

원인
4번이 발생한 원인은 2번 과정에서 select 쿼리 조건에 사용되는 데이터를 수정해버렸기 때문이다.
즉, 2번 이후에 status == ENABLED 인 데이터는 DB에 5개 밖에 존재하지 않는다.
이 상태에서 limit 5,10 을 실행했으니 데이터를 가져오지 못하는게 당연한다.

해결 방법
jojoldu 님 블로그에 이 문제의 원인 및 해결방법에 대하여 자세하게 설명이 나와있다.
https://jojoldu.tistory.com/337

간단하게 요약하면 아래 두 가지 방법을 통해 해결이 가능하다.

  • Cursor-based ItemReader 사용하기
    • 가장 무난하고 안전한 방법인거 같다.
    • 커넥션 타임아웃에 주의해야 한다.

  • 항상 첫번째 페이지 읽기
    • processor, writer 에서 읽어왔던 모든 데이터를 update 한다면 사용 가능
    • 그렇지 않은 경우에는 무한루프가 발생할 수 있을 거 같다.

  • 한가지 방법 더 추가!
    • AbstractPagingItemReader 를 구현하여 직접 커서기반 페이징 쿼리를 만들 수도 있다.

참고
Cursor-based ItemReader vs Paging ItemReader
https://renuevo.github.io/spring/batch/spring-batch-chapter-3/

JpaCursorItemReader
https://jojoldu.tistory.com/551

profile
백엔드 개발자

0개의 댓글