📚FOS Study
홈카테고리
홈카테고리
📚FOS Study

개발 학습 기록을 정리하는 블로그입니다.

바로가기

  • 홈
  • 카테고리

소셜

  • GitHub
  • Source Repository

© 2025 FOS Study. Built with Next.js & Tailwind CSS

목록으로 돌아가기
☕java/ spring-framework

Batch와 JdbcCursor

약 3분
GitHub에서 보기

Batch와 JdbcCursor

  • Cursor 방식이란 : 전체 데이터를 메모리에 올리지 않고, DB 서버와의 연결을 유지하며 레코드를 한 줄씩 가져오는 것

Cursor의 동작 원리: "Streaming"

Cursor 방식은 DB 서버 내부에 **커서(포인터)**를 생성하고, 클라이언트가 요청할 떄마다 한줄씩(또는 Fetch Size 만큼) 데이터를 넘겨준다.


  • Cursor Open : 쿼리가 실행되면 DB 서버는 결과 데이터를 준비하고, 첫 번째 레코드를 가리키는 커서를 메모리에 생성한다.
  • Fetch : 애플리케이션이 read()를 호출하면, DB는 현재 포인터가 가리키는 데이터를 보내고 포인터를 다음으로 이동시킨다.
  • Close : 모든 데이터를 읽거나 작업이 끝나면 커넥션을 닫고 리소스를 해제한다.

궁금증 : Cursor가 열리고 해당 테이블에 변화가 생기면 어떻게 될까?

  • 데이터베이스의 **격리 수준(Isolation Level)**과 커서의 종류에 따라 결정된다.
  • Spring Batch의 JdbcCursorItemReader를 사용할 떄 일반적인 RDBMS 환경에서는 "쿼리가 실행된 시점의 스냅샷을 기준으로 동작하는 것이 기본이다.

MVCC(Multi Version Concurrency Control)의 역할

  • 대부분의 현대적인 DB(MySQL InnoDB, Oracle, PostgreSQL)는 MVCC를 사용한다.
    • 동작 방식 : 쿼리가 시작되는 시점에 데이터의 버전(Snapshot)을 고정한다
    • 추가/삭제 발생 시 : 커서가 데이터를 읽는 도중 다른 트랜잭션이 Row를 추가하더라도, 현재 커서의 스냅샷에는 해당 데이터가 존재하지 않으므로 무시된다.
      • 다른 트랜잭션이 Row를 삭제하더라도, 현재 커서는 Undo Log나 Rollback Segment에 저장된 이전 버전의 데이터를 찾아내어 읽는다.

즉, 중간에 데이터가 변해도 커서가 읽는 결과 데이터셋은 변하지 않는 것이 일반적이다.

궁금증 : 커서를 열고 오래동안 배치를 수행하면 어떤 점이 리스크인가?

1. 리소스 점유와 성능 저하

  • Undo Log 누적 : 배치가 종료될때까지 DB는 배치가 읽기 시작한 시점의 데이터를 복구하기 위해 관련 Undo 데이터를 삭제하지 못하고 계속 쌓아야 한다.
    • 이로 인해 DB의 Undo 영역이 꽉 차면 다른 일반 사용자의 UPDATE/DELETE 쿼리가 실패하거나, 배치가 Snapshot too old 에러로 뻗을 수 있다.
  • Connection 점유 : 커서는 데이터를 다 읽을 떄 까지 커넥션을 물리적으로 계속 잡고 있는다. 커넥션 풀이 부족한 상황이라면 다른 API 요청이 타임아웃 날 수 있는 원인이 된다.

2. 네트워크 및 소켓 불안정성

  • 오래 실행되는 커넥션 : 배치가 1~2시간 이상 돌아간다면, 중간에 네트워크 장비(L4나 스위치 등)나 DB 설정에 의해 Idle Connection으로 판단되어 강제 종료될 위험이있다.

3. 결론 : "언제 Cursor를 써야 할까?"

상황Cursor 방식 (JdbcCursorItemReader)Paging 방식 (JdbcPagingItemReader)
데이터 양중소규모 (수만 ~ 수십만건)대규모 (백만 건 이상)
수행 시간짧고 굵게 끝날 때매우 오래 걸릴 떄
정합성배치 시작 시점의 스냅샷이 중요할 때중간에 데이터가 변해도 상관없거나 정렬이 명확할 떄
재시작처음부터 다시 시작해야 함실패한 페이지부터 재시작 가능
java 카테고리의 다른 글 보기수정 제안하기
목차
  • Batch와 JdbcCursor
  • Cursor의 동작 원리: "Streaming"
  • 궁금증 : Cursor가 열리고 해당 테이블에 변화가 생기면 어떻게 될까?
  • MVCC(Multi Version Concurrency Control)의 역할
  • 궁금증 : 커서를 열고 오래동안 배치를 수행하면 어떤 점이 리스크인가?
  • 1. 리소스 점유와 성능 저하
  • 2. 네트워크 및 소켓 불안정성
  • 3. 결론 : "언제 Cursor를 써야 할까?"