Cache는 간단히 말해서 나중의 요청에 대한 결과를 미리 저장했다가 빠르게 사용하는 것이다.
컴퓨터에서 중요한 메인 데이터들은 전원이 꺼져도 저장되는 SSD, HDD 등의 Secondary Memory에 저장된다. Secondary Memory에 저장된 데이터들은 장기적으로 안정적이게 저장될 수 있지만, 기술 한계상 데이터를 IO 하는 속도가 느리다.
그렇기 때문에 컴퓨터에서는 데이터 처리에 바로 필요한 데이터를 Main Memory인 RAM에 끌어놓거나, CPU에서 빠르게 접근할 수 있는 CPU Registers, Cache Memory의 형태로 저장하여 더 빠르고 쉽게 접근할 수 있도록 한다.
애플리케이션 서버(Spring JPA?)가 DB에 접근할 때를 예로 들어보면, DB에 연결하여 데이터를 가져오는 것을 Secondary Memory로, 서버의 메모리나 가까운 캐시서버에서 데이터를 가져오는 것을 Main Memory, Cache Memory로 비유할 수 있다.
JPA의 Cache는 Database보다 더 빠른 Memory에 더 자주 접근하고 덜 자주 바뀌는 데이터를 저장할때 적합하다.
네트워크를 통해 데이터베이스에 접근하는 시간 비용은 애플리케이션 서버에서 내부 메모리에 접근하는 시간 비용보다 수만에서 수십만 배 이상 비싸기 때문에, 조회한 데이터를 메모리에 캐시해서 데이터베이스 접근 횟수를 줄이면 애플리케이션 성능을 획기적으로 개선할 수 있다.
영속성 컨텍스트 내부에는 엔티티를 보관하는 저장소가 있는데, 이를 1차 캐시라고 한다.
1차 캐시는 영속성 컨텍스트 내부에 있으며, entityManager
로 조회하거나 변경하는 모든 엔티티는 1차 캐시에 저장된다.
1차 캐시는 끄고 켤 수 있는 옵션이 아니며, 사실상 영속성 컨텍스트 자체가 1차 캐시라고 할 수 있다.
일반적인 웹 애플리케이션 환경에서 1차 캐시는 트랜잭션이 시작하고 종료할 때 까지만 유효하다. OSIV를 사용해도 클라이언트의 필터로 요청이 들어오고 나갈 때까지만 남아있는다.
1차 캐시의 동작 과정을 간단하게 표현하면 다음과 같다.
- 1차 캐시에 엔티티가 없으면 데이터베이스에서 엔티티를 조회한다.
- 엔티티를 1차 캐시에 보관한다.
- 1차 캐시에 보관된 결과를 반환한다.
- 이후 같은 엔티티를 조회하면 1차 캐시에 같은 엔티티가 있으므로 데이터베이스를 조회하지 않고 1차 캐시의 엔티티를 그대로 반환한다.
같은 엔티티가 있으면 객체 동일성을 보장한다. (==)