[MyBatis] MyBatis 캐시에 대해 알아보기(1)
아주 오~~~랜만에 포스팅이다. 1년전 이맘때쯤 써야지 했던 내용인데 귀차니즘 신이 와서 묵혀두었다가 이제야 쓰게되었다.
하도 오랜만이라 내용을 많이 까먹었기에 오늘은 포스팅 내용중 반만 쓰고 나머지 반은 다음번 포스팅에 쓸 예정이다.
일단 블로그내에 모든 포스팅이 그렇지만 포스팅 내용은 내가 직접 테스트 해보고 알게된 내용을 공유하는 것이기 때문에
정확하지 않을 수 있다
오늘은 Mybatis 에서 제공하는 캐시에 대해서 알아보기로 하자.
우선 일차적으로 캐시가 뭔지부터 알아보자.
캐시란 "캐시(cache, 문화어: 캐쉬, 고속완충기, 고속완충기억기)는 컴퓨터 과학에서 데이터나 값을 미리 복사해 놓는 임시 장소를 가리킨다. 캐시의 접근 시간에 비해 원래 데이터를 접근하는 시간이 오래 걸리는 경우나 값을 다시 계산하는 시간을 절약하고 싶은 경우에 사용한다. 캐시에 데이터를 미리 복사해 놓으면 계산이나 접근 시간 없이 더 빠른 속도로 데이터에 접근할 수 있다." 라고 위키피디아에 써있다.
때문에 캐시는 자주 사용되는 동일한 데이터 혹은 잘 변하지 않는 데이터를 메모리에 올려놓고 데이터가 필요한 순간 메모리에 올려놓은 데이터를 다시 사용함으로써 원래 데이터에 접근하는 시간을 절약할때 사용한다.
이제 본격적으로 MyBatis의 캐시에 대해서 알아보자.
글의 제목을 봐서 알겠지만 MyBatis는 자체적으로 캐시를 제공한다. 내가 알고있는 선에서 MyBatis 는 크게 2종류의 cache 를 제공한다. 하나는 Local cache 다른 하나는 Second level cache 이다. 오늘 포스팅 내용은 Local cache이다.
- Local cache
Local cache 는 MyBatis 에서 별도의 설정을 하지 않아도 항상 켜저있는 cache이다. 이 Local cache는 적용 범위만 조정가능한데 config 파일에 다음과같이 작성하면 적용 범위가 조정가능하다.
속성은 STATEMENT, SESSION 둘중에 하나로 선택가능하고 Default 는 SESSION 이다.
그렇다면 둘의 차이점이 뭔지 알아보자.
A. SESSION
- 기본적으로 적용되어 있는 설정으로 MyBatis 를 사용하면서 특별한 옵션을 적용하지 않았다면 Local cache 의 적용범위는 SESSION으로 적용 되어 있는 상태이다.
- SESSION을 적용했을때 cache의 정보의 생존범위는 session이 유지되는 순간까지 이다. 즉 Transaction이 끝나거나(commit이나 rollback) 아니면 insert, update, delete 가 실행되면 Local cache가 보유하고 있던 cache 정보는 폐기된다.
- autoCommit을 실행시켜놓으면 쿼리를 실행할때마다 commit을 하기때문에 session에서 캐시가 유지되는지 확인하기 힘들다.
코드 - 반복문을 이용해서 동일한 검색조건(Map)으로 select 쿼리를 3번씩 호출하는 함수를 총 10번 호출할 것이다.
- Local cache 를 SESSION으로 적용후 위의 코드를 실행시키면 결과는 다음과같다.
결과
이해를 쉽게 돕기위해서 [N]번째 시도 라는 표현은 함수호출 횟수를 뜻하고 A,B,C 번째 시도는 함수안에 반복문에서 동일조건으로 쿼리를 했을때이다.
예를들어 [1]번째 시도를 해석해보면 1번째 의 함수 호출과 함수안에서의 반복문을 통한 A,B,C 번의 총 3번의 쿼리를 시도했다.
- [1] 번째 시도를 보면 알겠지만 [1]번째 시도의 A번째 시도에서 데이터를 찾는데 시간(1820ms)가 소모되었지만 반복문을 통해서 동일한 데이터를 다시 찾을때(B,C번째의 시도)는 cache의 정보를 사용하기에 시간(0~1ms)을 거의 소모하지 않았다.
- 그리고 또한 [4]번째 시도와 [7]번째 시도를 보면 알겠지만 동일한 조건을 갖는 데이터를 찾기를 시도하는데 각각 시간(1346ms, 1343ms)을 소모한다. 즉 [4]번째 시도의 A번째 시도에서 데이터를 캐싱하고 B,C번째에서 캐싱을 사용하지만 반복문이 끝나고 함수가 끝나는 시점에서 Commit이 일어나고 이에따라 캐싱되어있던 데이터트 폐기된다. 그 후 [7]번째에서 같은 데이터를 다시 찾을때 다시 시간(1343ms)을 시도하고 함수가 끝날때까지 다시 캐싱을 유지한다.
B. STATEMENT
- Config 설정에서 캐싱 범위를 STATEMENT로 하면 cache정보의 생존범위는 Statement 이다.
- 내가 이해하고있는 statement란 (select, update, insert, delete) 처럼 mapper에 정의된 액션 하나당 하나의 statement로 이해하고 있다(정확하지 않을 수 있다....) 때문에 Config를 STATEMENT로 바꾼후 SESSION과 동일한 코드를 한다면 다음과 같은 결과가 나온다.
결과
-SESSION 과는 다르게 commit이 되지 않았지만 [1]번째의 A,B,C번째 시도에 각각 데이터를 찾는데 시간이소모된다. 즉 statement 하나가 끝나면 바로 캐시 데이터를 폐기하고 다음번에 데이터를 찾을때 다시금 새로운 데이터를 찾는데 시간을 소모한다.
- 내가 이해한 상태에서 보자면 Local cache 범위를 statement로 설정하고 일반적으로 Mapper를 구성해서 사용하면 거의 cache를 사용하지 않는 것과 비슷한(local cache 자체를 끌 수는 없기때문에 똑같지는 않을것이라 생각한다) 효과를 낼 것이라고 생각한다.
간단하게 요약정리하자면
1. MyBatis에는 Local cache라는게 있는데 이녀석은 끌 수없고 항상 켜져있다.
2. 이녀석은 SESSION과 STATEMENT라는 설정 범위를 갖고있고 SESSION이 기본값이다.
3. STATEMENT와 SESSION의 차이는 캐시데이터의 생존범위이다.
4. 생존범위 차이에 대해서 궁금하면 위의 포스팅을 읽어보자.ㅎ
오늘의 포스팅 내용은 여기까지이다. 원래 Second level cache도 쓰고 싶었지만 내용이 생각이 안나서.. 다시 정리하고 쓸 예정이다...
포스팅 내용을 준비하면서 다음 사이트를 많이 참조했다. http://moi.vonos.net/java/mybatis-caching/
누군가에게는 작은도움이 되었기를 바라면서 오늘의 포스팅 끝~