인프런 커뮤니티 질문&답변

jdkjfkd fjfjdk님의 프로필 이미지

작성한 질문수

자바 ORM 표준 JPA 프로그래밍 - 기본편

준영속 상태

다른 서버에서 DB 업데이트시 캐시에 있는 엔티티는 어떻게 될까요?

작성

·

2.7K

9

find시에 캐시를 먼저 뒤져서 있다면 재사용한다고 하셨는데요

다른 서버에서 해당 DB 값을 바꾼다면 이런것도 dirty checking해주나요?

이런 케이스에서는 캐시를 업데이트 해야 할 것 같은데요?

답변 1

34

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. jdkjfkd fjfjdk님 좋은 질문입니다.

find에서 조회하는 캐시는 정확히는 영속성 컨텍스트, 또는 1차 캐시라고 합니다. 이 캐시는 우리가 일반적으로 말하는 애플리케이션 전체에서 공유하는 캐시가 아니라, 해당 트랜잭션의 시작과 끝에서만 짧게 유지되는 캐시입니다. 쉽게 이야기하면 특정 한 유저의 API 호출의 시작과 끝 사이에서 그 유저에게만 유지되는 짧은 캐시입니다. (설명을 돕기위해 유저라고 설명했지만 정확히는 트랜잭션을 시작할 때 생성되고, 트랜잭션이 끝날때 지워지는 캐시 입니다.)

그래서 같은 트랜잭션 안에서 같은 엔티티를 조회할 때만 캐시가 히트됩니다. (그래서 실무에서 이 1차 캐시로 성능 이득을 얻는 일은 많지 않습니다.)

다음으로 변경에 대한 부분을 설명드릴께요 :)

앞서 설명드린대로 트랜잭션 안에서만 캐시가 유효범위를 가지기 때문에, DB에 맞추어 캐시를 업데이트 하거나 더티 채킹을 하지 않습니다. 그리고 한다고 해도 다음에 설명드릴 내용 때문에 정확하게 맞출 수 도 없습니다.

예를 들어서 JPA를 사용하지 않고 자바로 직접 SQL을 사용한다고 가정하겠습니다. SQL로 상품 정보를 조회했는데 조회 당시 가격이 5000원인 것을 확인하고, 내가 그 가격에 500원을 더해서 정확히 5500원을 만들고 싶었는데, 중간에 누군가 가격은 6000원으로 변경해버리면 어떻게 해야할까요? 중간에 체크하는 로직을 넣으면 가능할 것 도 같지만, 체크를 통과하는 시점의 미묘한 지점에 누군가 6000원으로 변경해버릴 수도 있습니다. 결론적으로 이런 문제는 SQL을 직접 사용해도 락을 걸지 않는 이상 단순하게 해결이 안됩니다.

JPA는 데이터베이스가 제공하는 락 기능을 적극 제공하고, 추가로 더 나아가서 낙관적 락이라는 기능도 제공합니다.

이 부분을 설명드리면 좋겠지만, 책에서도 수십 Page로 풀어서 설명을 해야 하는 부분이어서, 자세한 내용은 JPA 책 16장 트랜잭션과 락, 2차 캐시 부분을 읽어보시길 권장드립니다^^

감사합니다.

로우 락을 거는 DBMS에서는 직접 SQL을 사용해 트랜잭션을 진행하면 로우 락으로 인한 성능 저하가 발생할 수 있지만

JPA를 사용하면 애플리케이션 레벨에서 트랜잭션을 진행해 X 락을 걸지 않고 엔티티를 수정한 후 낙관적 락으로 변경 사항을 적용할지 말지 정한다로 이해할 수 있을까요?

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. acisliver님

JPA를 사용해도 X락을 걸거나 또는 낙관적 락을 사용하도록 선택을 해야 합니다.

자세한 내용은 JPA 책 16장 트랜잭션과 락, 2차 캐시 부분을 읽어보시길 권장드립니다^^

답변 감사드립니다😆

자세한 내용이 궁금해서 책을 사버렸네요!

좋은 하루 되세요!