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

Minsu Kang·2021년 12월 14일

얼마전 스프링 배치를 이용해 청크단위로 데이터를 처리하다가 데이터를 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

0개의 댓글