Post

(MyBatis) Cache

간단히 정리하면,

MyBatis는 2가지 캐시를 제공한다. local session cache, second level cache

second level cache

  • https://idea-sketch.tistory.com/31
  • mapper namespace 단위로 적용. <cache/> 구문.
  • 캐시 설정 파라미터 : 캐시 size, eviction 방식(e.g., LRU), flushInterval 등
  • session commit 한다고 캐시가 사라지지 않는다. (설정 파라미터에서 눈치 챌 수 있다.)

local session cache

  • https://mybatis.org/mybatis-3/java-api.html
  • Local Cache 항목 참조
  • https://idea-sketch.tistory.com/30
  • 별도 설정 없이 기본으로 항상 활성화 되어 있는 캐시.
    • circular references 해결(및 speed up) 목적이라 실제로 비활성화는 불가능하고 적용 범위를 작게 조정하면 비활성화 한 것 처럼 세팅 가능.
  • 같은 쿼리를 같은 파라미터로 호출하면 캐시에서 가져온다.
  • 적용범위 SESSION(default)
    • update, commit, rollback, close 시 clear 됨.
    • 하지만 update 시에는 제대로 clear 되지 않는다는 예제가 많이 있다.
    • useCache, flushCache 옵션 조절하여 특정 statement 단위로 비활성화 가능
      • 이상한 점은 2nd level cache는 기본적으로 비활성화 상태라고 했다. 그러나 useCache 옵션은 docs에 따르면 2nd level cache 관련 옵션인데, 이를 조절해야 캐시가 제대로 비활성화 된다는 것은 2nd level cache도 기본적으로 적용이 되고 있다는 것인가? 아니면 docs 설명이 잘못되어 있는 것인가?
  • 적용범위 STATEMENT
    • 캐시 적용 범위가 구문(SELECT, INSERT, UPDATE, DELETE, …)로 제한됨. 사실상 캐시가 없는 것과 비슷하다.

참고로 MyBatis가 캐싱하는 대상은 쿼리 구문이 아니라, 쿼리 수행 결과다.

  • 최근, 자주 사용되는 쿼리 구문을 캐시하여 SQL parsing 비용을 절감하는 것은 DBMS 단에서 한다.
    • 물론 DBMS 단에서도 쿼리 구문 캐싱 뿐만 아니라, 쿼리 수행 결과도 캐싱하도록 설정 할 수도 있다.
  • 그리고 PreparedStatement에 대한 캐싱도 있는데, 이 것은 앱 단의 JDBC driver에서 수행하는 캐싱이다.
    • 참고) MyBatis preparedStatement는 #{}이고, 취약한 그냥 statement는 ${}이다.
This post is licensed under CC BY 4.0 by the author.