들어가기
네트워크를 통해 DB에 접근(Ex. 실제 운영하는 서비스)하는 시간 비용은
애플리케이션 서버 내부 메모리에 접근하는 시간보다 훨씬 비싸다.
이러한 부담을 줄이고 성능을 높이기 위해 Hibernate와 같은 JPA 구현체들은 캐시(Cache)를 지원한다.
캐시를 사용하면 매번 필요한 데이터를 DB에서 조회하지 않고,
캐싱해둔 데이터를 통해 DB 접근 횟수를 줄여 애플리케이션의 성능을 향상 시킬 수 있다.
💡 1차 캐시 (First Level Cache)
1차 캐시란?
: JPA 영속성 컨텍스트 내부에 존재하는 캐시(Chache)로, EntityManager로 조회/변경하는 모든 엔티티가 1차 캐시에 저장된다.
✔️ 1차 캐시 특징
- 1차 캐시는 트랜잭션 범위 내에서만 동작하여 트랜잭션이 시작하고 종료될 때까지만 살아있다.
- 트랜잭션 Commit / Flush 하면, 1차 캐시에 있는 엔티티의 변경 사항들이 데이터베이스에 반영된다.
- 영속성 컨텍스트 자체가 1차 캐시이기 때문에, 1차 캐시는 끄고 켤 수 있는 옵션이 아니다.
- Hibernate에서 1차 캐시를 기본적으로 제공한다.
✔️ 1차 캐시 조회 과정
- 1차 캐시에서 해당 Key에 대한 Entity가 존재하는지 조회한다.
- 존재하면, DB를 조회하지 않고 메모리에 있는 1차 캐시에서 해당 Entity를 조회한다.
- 존재하지 않으면, DB에서 조회 후, 해당 Entity를 1차 캐시에 저장하여 영속 상태로 만들고 반환한다.
💡 2차 캐시 (Second Level Cache)
2차 캐시란?
: 애플리케이션 내에서 동작하는 캐시로, JPA 공유 캐시라고 부르기도 한다.
✔️ 2차 캐시 특징
- 2차 캐시는 애플리케이션이 종료될 때까지 살아있다.
- 분산 환경이나 클러스터링 환경에서 캐시는 애플리케이션보다 더 오래 유지될 수 있다.
- EntityManager를 통해 데이터를 조회할 때 먼저 2차 캐시에서 데이터를 찾고, 데이터가 존재하지 않을 경우에 데이터베이스에서 찾게 된다. 따라서, 2차 캐시를 적절히 활용하면 데이터베이스에 접근하는 횟수를 줄일 수 있다.
- 2차 캐시는 동시성을 극대화하기 위해 캐시한 데이터를 그대로 반환하지 않고, 복사본을 만들어서 반환한다.
- 캐시한 데이터를 그대로 반환하면 여러 곳에서 동시에 같은 데이터를 수정하는 문제가 발생될 수 있다.
- 이때, Lock을 걸어서 동시성 문제를 해결할 수 있지만, 성능 개선의 이점을 가져갈 수 없기 때문에 복사본을 만드는 것이다.
- 영속성 컨텍스트가 다를 경우, 객체의 동일성을 보장하지 않는다.

✔️ 2차 캐시 조회 과정
- 영속성 컨텍스트는 엔티티가 필요할 때 먼저 2차 캐시를 조회한다.
- 2차 캐시에 필요한 엔티티가 존재하지 않으면, 데이터베이스를 조회한다.
- 조회한 결과를 2차 캐시에 보관한다.
- 2차 캐시는 보관하고 있는 엔티티를 복사하여 반환한다.
- 2차 캐시에 저장된 엔티티를 조회하면, 복사본을 만들어서 반환한다.
✔️ Hibernate에서 지원하는 2차 캐시 종류
1. Entity 캐시
엔티티 단위로 캐시하는 방법으로,
식별자(id)로 엔티티를 조회하거나, 컬렉션이 아닌 연관 관계에 있는 데이터를 조회할 때 사용한다.
2. Collection 캐시
엔티티와 연관된 컬렉션을 캐시하는 방법으로, 컬렉션이 엔티티를 담고 있을 경우 식별자(id) 값만 캐시한다.
3. Query 캐시
쿼리 캐시는 캐시한 데이터 집합을 최신 데이터로 유지하기 위해 쿼리 캐시를 실행하는 시간과 쿼리 캐시가 사용하는 테이블들의 가장 최근 변경된 시간을 비교한다. 쿼리 캐시를 적용하고 난 후, 쿼리 캐시가 사용하는 테이블에 변경 사항이 있으면 DB에서 데이터를 읽어와 쿼리 결과를 다시 캐시한다.
✔️ Query 캐시와 Collection 캐시 사용 시, 주의할 점
- 쿼리 캐시와 컬렉션 캐시는 결과 집합의 식별자 값만 캐시한다.
- 따라서, 쿼리 캐시나 컬렉션 캐시만 사용하고 대상 엔티티에 엔티티 캐시를 적용하지 않으면 성능이 떨어진다.
출처
긴 글 읽어주셔서 감사합니다 🍀
잘못 작성된 내용은 피드백 주시면 반영하겠습니다 😎
'JPA' 카테고리의 다른 글
[JPA] Hibernate Dialect(방언) (0) | 2024.01.02 |
---|---|
[JPA] JPA 영속성 컨텍스트 (0) | 2023.12.21 |
[JPA] ORM과 JPA (0) | 2023.12.18 |