다음 코드에서 문제점이 무엇이었을까? 바로 안다면 댕고수..
발생 상황 간단히 재구성
- DB에는 파일 이름만 저장되어 있다. ex) test.png
- prefix는 property로 관리하고 있다. ex) http://test.com
- id로 파일 이름을 찾아와서 전체 url을 생성 ex) http://test.com/test.png
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class TestService {
private final TestMapper testMapper;
public void test() {
final List<Integer> idList = List.of(1, 2, 3, 1);
idList.forEach(id -> {
System.out.println(greetings(id));
});
}
private TestDto greetings(final int id) {
final String prefix = "http://test.com/";
final TestDto url = testMapper.getUrl(id);
url.setUrl(prefix + url.getUrl());
return url;
}
}
@Data
public class TestDto {
private String url;
}
<select id="getUrl"
parameterType="int"
resultType="com.example.datasource.dto.TestDto">
SELECT url FROM test WHERE id=#{id}
</select>
쿼리로그를 찍어봤다.
이상한점 발견..
마지막 쿼리는 수행되지 않는 것을 확인 했다.
❗️
@Transactional
어노테이션은 같은 조회쿼리를 수행하면 캐싱을 한다!
- (mysql, mybatis 환경)
@Transactional
어노테이션을 제거 하고 실행하지만 해당 메소드가 트랜잭션이 필요한 상황이어서 @Transactional
어노테이션을 제거할 수 없었다.
mybatis 옵션에서 캐시를 바로 적용하도록 변경
<select id="getUrl"
parameterType="int"
flushCache="true"
resultType="com.example.datasource.dto.TestDto">
SELECT url FROM test WHERE id=#{id}
</select>
private TestResponse greetings(final int id) {
final String prefix = "http://test.com/";
final TestDto url = testMapper.getUrl(id);
return new TestResponse(prefix + url.getUrl());
}