이론 정리/Spring boot

MyBatis 의 cache

철매존 2025. 6. 9. 08:03
728x90
반응형

MyBatis 의 cache

MyBatis 에는 두 종류의 캐시가 존재한다.

  • 1차 캐시 (Local / Session Cache)
  • 2차 캐시 (Global / Mapper Namespace Cache)

1차 캐시

  • SqlSession 레벨의 캐시이다.
    • 즉 SqlSession 내에서만 유효하기 때문에 서로 다른 SqlSession 간에는 공유되지 않는다.
  • Default로 활성화되어 있다.

동작 방식

  • SQL 문장 수행 시 결과를 캐싱하여, 이전과 완전히 동일한 문장이 오면 캐싱된 데이터를 반환한다.
    • 즉 완전히 동일한 문장과 파라미터여야 한다는 것
  • SqlSession 이 닫히거나 CUD작업이 발생하면 1차 캐시는 비워진다.

2차 캐시

  • SqlSessionFactory 레벨의 캐시이다.
    • 즉 동일한 Mapper Namespace 내의 모든 SqlSession 이 공유한다.
  • Default 는 비활성화되어 따로 설정해야 활성화된다.

동작 방식

  • XML 파일에 <cache/> 태그를 추가해서 활성화한다.
  • SqlSessionFactory 내의 SqlSession 에서 뭔가 결과를 가져오면 해당 Namespace 의 2차 캐시에 저장
    • 참고로 이게 골때리는게, 얘는 select 시에 캐싱되는게 아니라 commit 되거나 close 되는 시점에 1차 캐시에 있던 내용이 2차 캐시로 옮겨진다.
      • 그래서 1차 캐시에 있다고 2차 캐시에 있다고 여겨서는 안되기도 하고, 디버깅이 아주 골때려진다.
  • 이후 다른 SqlSession 에서 동일한 Namespace 의 같은 쿼리를 수행하면 2차 캐시에서 데이터를 가져온다.
  • 요것도 위와 비슷하게 Namespace 내에서 CUD가 발생하면 기본적으로 비워진다.

장점

  • 성능 향상
  • DB 부하 감소
  • 네트워크 트래픽 감소

단점

  • 데이터 일관성
    • 여러 server 에서 DB를 수정한다면? 문제 발생 가능
    • 분산 환경에서 매우 큰 단점이다.
    • 참고로 이거는 1차 캐시는 이럴 일이 적고, 2차 캐시에서 발생할 가능성이 높다.
  • 메모리 사용량 증가
    • OOM 이 발생할 수 있다.
    • 특히, 배치 등에서 막 List 를 조회하거나 너무 많은/큰 데이터를 캐시하면 문제가 발생할 수 있다.
      • (사실 이거때문에 이 글을 씀)
        • 예를 들어 배치에서 수십만 데이터를 가진 List 를 조회하는 쿼리에 2차 캐시가 걸려 있으면 큰일남
  • 복잡성 증가
    • 특히 2차 캐시의 경우는 캐시 크기에 대한 문제나 갱신 주기, 정책 등을 잘 해 두어야 한다.
반응형