문제
하나의 트랜잭션 내에서 동일한 파라미터로 쿼리문을 반복 호출했을 때,
쿼리가 내부적으로 한 번만 실행되는 문제가 발생했다.
테이블에 동일한 데이터를 여러 번 삽입하면 무결성 제약조건을 위반하여 오류를 발생시켜야 함에도 불구하고,
하나의 트랜잭션 내에서 쿼리가 한 번만 실행된 것으로 인식되어
데이터베이스에 정상적으로 등록되는 상황이었다.
원인
MyBatis 캐시
- 1차 레벨 캐시 : Local Cache
- 2차 레벨 캐시
MyBatis의 캐시가 원인이었다. 기본적으로 MyBatis는 로컬 캐시를 세션 단위로 설정되어있는데, 이 경우 하나의 세션(트랜잭션) 내에서 동일한 입력 매개변수로 동일한 쿼리를 반복 실행하면 로컬 캐시에 저장된 객체를 재사용한다.
참고 : https://mybatis.org/mybatis-3/java-api.html
해결
방법1. MyBatis 설정 파일에서 로컬 캐시 범위 변경
: MyBatis 설정 XML파일(MyBatis-config.xml) 에서 localCacheScope=STATEMENT 로 변경
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="localCacheScope" value="STATEMENT" />
</settings>
</configuration>
1) SESSION (기본값)
트랜잭션 commit, rollback, 세션 close 될 때 캐시가 제거된다.
2) STATEMENT
sql 쿼리문 실행될때마다 캐시가 제거된다.
방법2. 코드에서 clearCache() 함수 호출
sqlSession.clearCache()
방법3. 특정 쿼리문만 캐시 설정 변경 (★)
: select문 속성에서 flushCache=true, useCache=false 설정
- 1차 캐시 비활성화 : flushCache=true
- 2차 캐시 비활성화 : useCache=false
<select id="" parameterType="java.util.Map" flushCache="true" useCache="false">
<!-- 내용 -->
</select>'SQL' 카테고리의 다른 글
| 오라클 프로시저, 함수 호출 (0) | 2024.12.23 |
|---|