☁️ Hibernate에서의 객체 캐싱

😶‍🌫️ 1차 캐시(First-Level Cache)

JPA의 Persistence Context에서 사용되는 핵심 메커니즘

영속성 컨텍스트 내부에서 트랜잭션 단위로 엔티티 인스턴스를 저장하고 관리하는 저장소

1차 캐시는 기본적으로 활성화되어 있으며 영속성 컨텍스트가 곧 1차 캐시라고 할 수 있음

 

트랜잭션을 Commit 하거나 Flush 할 경우 1차 캐시에 있는 엔티티의 변경 사항들을 DB에 반영

 

❄️ 1차 캐시의 조회 동작

1. 조회 시 식별자(ID)를 통해 1차 캐시에 데이터가 있는지 확인하고, 데이터가 있으면 가져옴

2. 1차 캐시에 데이터가 없으면 DB에 데이터 요청

3. DB에서 받아온 데이터를 재사용할 수 있도록 1차 캐시에 저장

 

 

😶‍🌫️ 공유 캐시(Shared Cache) / 2차 캐시(Second-Level Cache)

1차 캐시는 트랜잭션 단위로 캐싱을 하기 때문에 애플리케이션 전체로 봤을 때 DB 접근 횟수를 획기적으로 줄이지는 못함

 2차 캐시는 애플리케이션 단위의 캐시를 지원해 여러 세션간에 데이터를 공유하고 DB에서 데이터를 다시 로드하는 오버헤드를 줄여줌

 

❄️ 2차 캐시의 조회 동작

1. 영속성 컨텍스트는 1차 캐시에 없는 엔티티가 필요할 경우 2차 캐시 조회

2. 2차 캐시에도 데이터가 없으면 DB에 데이터 요청 후 2차 캐시에 보관

3. 2차 캐시에 보관하고 있는 엔티티의 원본이 아닌 복사본을 반환

 

🤔 왜 엔티티 원본이 아닌 복사본을 반환하지?

애플리케이션 단위 캐싱일 경우 여러 곳에서 같은 객체를 수정할 경우 충돌이 일어날 수 있다.

 

해당 문제를 해결하기 위해 객체에 락을 걸면 한 번에 하나의 스레드만 접근할 수 있기 때문에 동시성이 떨어짐

 동시성을 극대화하기 위해 캐시한 객체를 직접 반환하는 것이 아닌 복사본을 만들어 반환

 

 

https://docs.jboss.org/hibernate/orm/5.4/userguide/html_single/Hibernate_User_Guide.html

https://tutorialseye.com/caching-objects-in-hibernate.html

https://velog.io/@dnjscksdn98/JPA-Hibernate-First-Level-Cache-Second-Level-Cache