본문 바로가기
카테고리 없음

Spring Batch Paging vs Cursor

by { 큐 } 2025. 7. 28.

 

배치를 돌릴 때 페이징 처리를 할 지 커서를 할 지 고민이 되는 때가 있다.

업무적으로 경험했던 많은 케이스들을 떠올려보면 해당하는 조건의 모든 데이터가 대상이 되기 때문에, 애초부터 쿼리를 잘 짜서 Cursor로 돌리는 것이 편하다.

 

PagingItemReader의 경우에는 데이터가 많아질수록 한 번의 쿼리 수행이 느려지는 단점이 있다. 또한, MyBatisPagingItemReader 쿼리 내에 paging 처리를 위한 파라미터를 따로 추가해줘야 하는 번거로움도 있다. (없으면 계속 첫 페이지를 돌리기 때문에 뜻밖의 장애와 마주칠 수 있다)

SELECT FOO
FROM BAR
WHERE TYPE = 'A'
OFFSET #{_skiprows} ROWS FETCH NEXT #{_pagesize} ROWS ONLY -- 추가 필요

 

 

하지만 페이징으로 배치 처리가 필요한 경우도 있을 수 있을 것 같다. 

MyBatisPagingItemReader 또는 JpaPagingItemReader의 조상인 AbstractItemCountingItemStreamItemReader 내에 setMaxItemCount라는 메소드가 있다. 가령 이번엔 1000개, 다음번엔 10000개만 조회해서 무언가를 해야하는 경우가 있다면 객체를 생성한 뒤에 setMaxItemCount로 조절할 수 있다.

MyBatisPagingItemReader<Item> reader = new MyBatisPagingItemReaderBuilder<Item>()
    .sqlSessionFactory(sqlSessionFactory)
    .queryId("com.example.ItemMapper.selectItems")
    .pageSize(100)
    .build();

reader.setMaxItemCount(1000);  // ✅ 100 * 10 = 1000건까지만 읽기

 

이건 실제로 job parameter로 전달 받았을 때 더 유용하게 쓸 수 있을 것 같다.