MyBatis의 Cache 설정

2012. 8. 2. 16:31

MyBatis의 캐시를 적용해보니 Mapper 단위로 캐시가 사용되어 insert, update, delete 명령을 실행할 때,  flush가 실행되지 않으면 select 명령을 실행할 때 변경전 캐시 내용이 출력되는 문제점이 있었다. 물론 CRUD 단위로 작성된 Mapper 라면 문제가 없겠지만, 조인한 결과를 읽기 위한 Mapper의 경우 select 명령을 실행할 경우에도 flush를 해줘야 하므로 캐시 이용의 이점을 얻을 수 없었다.

캐시의 사용은 CRUD가 한 세트로 작성되는 mapper에서만 사용해야 할 것 같다.

Cache

MyBatis는 쉽게 설정 가능하고 변경 가능한 강력한 트랜젝션 쿼리 캐싱을 포함하고 있다. MyBatis 3 구현체는 더 강력하고 훨씨 쉽게 설정할 수 있도록 많은 변화가 있었다.

기본적으로, 세션 주기 동안 캐시 데이터가 전적으로 사용될 수 있도록 로컬 세션 캐싱만 활성화 되어 있다. Global level caching을 활성화 하기 위해 SQL Mapping 파일에 간단하게 한 줄만 추가하면 된다.

<cache/>

이 한 문장이 다음과 같은 영향을 준다:

  • 맵핑 구문 파일 내의 모든 select 구문의 결과는 캐싱될 것이다.
  • 매핑 구문 파일 내의 모든 insert, update, delete 구문은 캐시에서 비워질(flush) 것이다.
  • 캐시에서 내보내기 위해 LRU(Least Recently Used; 최빈값 이용) 알고리즘을 사용할 것이다.
  • 캐시는 시간 기반 스케줄로 캐시를 비우지 않을 것이다.(캐시를 비우는 간격이 없다.)
  • 캐시는 1,024개의 쿼리 결과를 담은 리스트나 객체들의 참조를 저장할 것이다.
  • 캐시는 읽기/쓰기 캐시처럼 취급할 것이다. 검색된 객체들은 다른 호출자나 스레드에 의해 잠재적인 수정이 없도록 공유되지 않고 안전하게 호출자에 의해 수정된다는 의미이다.
이 모든 속성들은 캐시 엘리먼트의 어트리뷰트들을 통해 수정될 수 있다. 예들 들어:
<cache eviction="FIFO" flushinterval="60000"
        size="500" readonly="true"/>

여기 더 발전된 설정은 60초마다 캐시를 FIFO(선입선출) 방식으로 비우고, 512개까지의 객체나 리스트들의 결과값을 저장하며, 객체는 읽기전용으로 사용된다. 따라서  스레드 안의 두 호출자 사이에서 수정하는 것은 충돌을 일으킬 수 있다.

가능한 캐시 내보내기 정책은 4가지가 가능하다:

  • LRU
  • FIFO
  • SOFT - Soft Reference: 가비지 컬렉터의 상태와 Soft Reference 규칙에 의해 삭제된다.
  • WEAK - Weak Reference: 가비지 컬렉터의 상태와 Weak Reference 규칙에 의해 더 적극적으로 삭제된다.


+ Recent posts