관리 메뉴

JIE0025

[리팩토링] Mapper 캐시 설정 변경으로 데이터 무결성 지키기 (MyBatis - useCache, flushCache) 본문

백엔드/이슈, 트러블슈팅

[리팩토링] Mapper 캐시 설정 변경으로 데이터 무결성 지키기 (MyBatis - useCache, flushCache)

Kangjieun11 2024. 4. 29. 19:57
728x90

 

.

 

✅ 개요

 

이전에 아래와 같은 상황이 발생했었는데...

 

https://jie0025.tistory.com/618

 

한 트랜잭션에서 동일한 데이터를 조회하면? (MyBatis의 캐싱전략과 localCacheScope 설정하기)

✅ 가정 학생이 존재한다. 학생은 학년별로 성적표를 출력할 수 있다. 학년당 2학기가 존재하고, 성적표 또한 학기별로 출력된다. 위의 이미지는 2학년 성적표를 조회하는 상황이다. 1학기, 2학

jie0025.tistory.com

 

 

정리하자면 

 

한 요청상황에서 (동일 트랜잭션) 
파라미터까지 똑같은 쿼리를 할 경우


MyBatis 는 내부 캐싱을 사용하고,
이에 따라 쿼리와 쿼리사이에서 
해당 엔티티의 값이 변경될 경우


이후 쿼리 상황에서  바뀐 값으로 출력된다.

 

 

 

 

 

이 문제가 Local에서만 일어나는 일이었어서 간단하게 설정파일을 변경하였고,

개발쪽에서도 잘 작동되는것을 눈으로 확인했다.

 

 

 


 

 

✅ 문제

근데  문제가 발생했다.

다른 애플리케이션단에서, 개발한 부분을 참조해서 실행시키고 있었는데

 

A 개발계에선 작동했지만,

B 개발계에선 작동하지 않는것이었다.

 

A개발계에 존재하는 파일을 호출해 사용하는것도 동일한데 

왜 둘에서 같은 결과가 나오지 않는지는 사실 알수가 없다.

 

 

어떤 애플리케이션이든, 
금융 IT에선 일단 잘 작동해야한다.

 

 

타 애플리케이션에서 작동하지 않는다는것은 결국, A개발계로 조치를 취해야한다는 의미였는데

 

위에서 해결한 방법 (local단)을

실제 운영되는 서비스에 넣게되면 모든 요청에 대해 캐시를 사용하지 않는다는 의미가된다

 

내가 만지고 있는 파트가 메인 도메인이었기 때문에

저 한줄로 굉장히 많은 비용이 발생하게 된다.

 

 

개발자는 코드 한줄도 책임감을 갖고 추가해야한다.

 

 

이 코드가 최종 배포버전에는 어울리지 않다 판단해,

다른 해결 방법을 찾기 시작했다.

 

 

 


 

 

✅ 해결과정

 

 

추가로 연계된 쪽에선 해당이슈 때문에 작동이 정상적으로 이루어지지 않는것을 보게되어

꼭 해결해야만 하는 이슈가 되었다. 

 

 

 

그리고, SQL쿼리마다 캐시 사용을 설정해줄 수 있다는점을 알게되었다. 

 

 

두가지 방법이 있는데, 

 

 

1. 사용하는 SQL SESSION을 이용하여 직접 캐시를 지우던지, 

SqlSession.clearCache();

 

2. Mapper 부분에서 캐시 설정을 통해   -- 캐시를 지워버리는 경우 

 useCache="false" flushCache="true"

 

 

1번의 경우

문제가 발생하는 부분에서

SQL Session 자체의 의존성을 가진 후 지워주어야하기 때문에 상대적으로 번거로운 방법이다. 

 

 

 

 

2번의 경우엔 SQL 문이 작성되어있는 xml파일에 한줄만 추가해주면 된다.

문제가 발생하는 쿼리문에만 설정하면 되기 때문에 가장 간편한 해결방법이다. 

 

 

 

<select> 의 default 캐시설정은 

useCache="true"
flushCache="false"

캐시를 사용한다, flush (캐시 초기화)는 사용X



여기에서 useCache = "false", flushCahce="true" 로 변경해주면,

원하는대로 캐시가 사용되지 않고, 반복되는 같은 쿼리문에서 문제가 발생하지 않게 된다!

 

 

<select id="selectTestTable"  
             parameterType="String"  
             resultType="int" 
             useCache="false" flushCache="true">    // ✪
       select col2 
       from session_test 
       where col1 = #{col1} 
</select>
 

 

 

 


 

references

 

https://blog.naver.com/tkstone/50193992290

 

MyBatis 내장 cache 에 대해서

MyBatis 에는 2가지 내장 Cache  가 있다. 1) local session cache 2) second level cache   ...

blog.naver.com