공부해봅시당

[JPA] 1차 캐시와 2차 캐시 (feat. 스프링 프레임워크 캐시) 본문

STUDY/Spring

[JPA] 1차 캐시와 2차 캐시 (feat. 스프링 프레임워크 캐시)

tngus 2024. 5. 8. 19:39

1차 캐시와 2차 캐시

 

1차 캐시(First Level Cache)

영속성 컨텍스트(Persistence Context)의 내부에는 엔티티를 보관하는 저장소가 있는데, 이것을 `1차 캐시(First Level Cache)`라고 부른다. 그래서 1차 캐시는 트랜잭션이 시작하고 종료할 때까지만 유효하다.

즉, 트랜잭션 단위의 캐시이다.

따라서 애플리케이션 전체로 보면 데이터베이스 접근 횟수를 획기적으로 줄이지는 못한다.

 

1차 캐시 특징

- 1차 캐시는 영속성 컨텍스트 내부에 있음

  -> 따라서 1차 캐시는 활성화하거나 비활성화할 수 있는 옵션이 아니고, 영속성 컨텍스트 자체가 사실상 1차 캐시

- 엔터티 매니저로 조회하거나 변경하는 모든 엔터티는 1차 캐시에 저장됨

- 트랜잭션을 Commit 하거나 Flush를 하게 되면 1차 캐시에 있는 엔터티의 변경 사항들을 데이터베이스에 반영함

- JPA를 스프링 프레임워크 같은 컨테이너 위에서 실행하면,

   트랜잭션을 시작할 때 영속성 컨텍스트를 생성하고 트랜잭션을 종료할 때 영속성 컨택스트도 종료함

 

1차 캐시 조작

1차 캐시는 엔터티 매니저 수준에서 자동으로 관리되고, 각 엔터티 매니저 인스턴스에 국한됨

이 캐시는 특별히 활성화할 필요 없이 JPA가 내부적으로 사용하는 기본 기능임

 

특징

- 자동화된 기능

엔터티 매니저는 영속화(persist), 조회(find), 업데이트 등의 작업을 수행할 때 자동으로 1차 캐시를 사용함

예를 들어 한 트랜잭션 내에서 동일한 엔터티를 여러 번 조회하면, 처음 조회할 때만 데이터베이스에서 데이터를 불러오고 이후 조회에서는 1차 캐시에서 데이터를 가져옴

 

- 트랜잭션 지속성

1차 캐시는 현재 트랜잭션 또는 엔터티 매니저 세션과 생명주기를 같이 함.

엔터티 매니저가 닫히거나, 트랜잭션이 종료되면 캐시로 사라짐

 

조작

그래서 직접적으로 조작하는 것은 제한적이지만, 일부 제한하는 방법이 있음

(아래 관련 내용에 대한 자세한 사항은 링크 참조할 것)

 

- 캐시 초기화

entityManager.clear();

 

- 엔터티 분리

entityManager.detach(entity);

 

- 트랜잭션 커밋 또는 롤백

entityManager.getTransaction().commit();

 

- 조회 캐시 활용

find() 메서드나 JPQL 쿼리를 사용해 데이터를 조회할 때, 자동으로 1차 캐시를 확인하여 해당 데이터가 이미 캐시에 있는지 먼저 검사함

이미 캐시에 있는 엔터티는 데이터베이스를 거치지 않고 바로 반환됨

 

 

2차 캐시(Second Level Cache)

JPA 구현체들은 애플리케이션 단위의 캐시를 지원하는데, 이것을 공유 캐시 또는 `2차 캐시(Second Level Cache)`라고 부른다.

2차 캐시를 적용하면 애플리케이션 조회 성능을 향상할 수 있다.

2차 캐시 적용 전
2차 캐시 적용 후

 

2차 캐시 특징

- 2차 캐시는 애플리케이션 단위의 캐시

   -> 따라서 애플리케이션을 종료할 때까지 캐시가 유지됨

- 2차 캐시를 사용하면 엔터티 매니저를 통해 데이터를 조회할 때 우선 2차 캐시에서 찾고, 없으면 데이터베이스에서 찾게 됨

   -> 그래서 2차 캐시를 적절히 활용하면 데이터베이스 조회 횟수를 획기적으로 줄일 수 있음

- 2차 캐시는 동시성을 극대화하려고 캐시한 객체를 직접 반환하지 않고 복사본을 만들어서 반환

   -> 만약 캐시한 객체를 그대로 반환하면 여러 곳에서 같은 객체를 동시에 수정하는 문제가 발생할 수 있는데

         이 문제를 해결하려면 객체에 락을 걸어야 함

         -> 이 과정에서 동시성이 떨어질 수 있음

   -> 락에 비하면 객체를 복사하는 비용은 아주 저렴하기 때문에 2차 캐시는 복사본을 반환하게 됨

 

2차 캐시 조작

2차 캐시는 엔터티 매니저 간에 공유될 수 있으며, 여러 세션과 트랜잭션에 걸쳐 엔터티의 데이터를 유지할 수 있

이 캐시는 명시적으로 활성화하고 구성해야 하며, 사용할 캐시 기술과 설정을 개발자가 선택해야 함

 

특징

- 수동 활성화 및 설정

2차 캐시는 기본적으로 비활성화되어 있음.

따라서 사용하려면 application.yml 파일이나 다른 구성 파일에서 명시적으로 활성화하고, 적절한 캐시 구현체를 설정해야 함

 

- 응용 프로그램 범위의 공유

활성화된 경우, 2차 캐시는 여러 엔터티 매니저와 트랜잭션에 걸쳐 공유됨

이를 통해 데이터베이스의 부하를 줄이고 전반적인 성능을 향상시킬 수 있음

 

그래서 2차 캐시를 위해서는 따로 설정을 해줘야 함

 

조작

JPA 스펙에는 2차 캐시를 지원하긴 하지만, JPA 자체는 인터페이스로만 구성이 되어 있다.

따라서 2차 캐시를 사용하기 위해서는 그 기능을 제공하는 JPA 구현체를 사용해야 한다.

Hibernate는 JPA 구현체 중 하나로, EhCache, Infinispan 등 다양한 캐시 프로바이더와의 통합을 지원하여 매우 강력한 2차 캐시 기능을 제공한다.

 

스프링부트에서는 주로 jpa를 사용할 때 gradle에 다음과 같은 jpa stater 패키지를 추가하게 될 것이다.

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
}

이 스타터 패키지에는 JPA를 위한 기본 구성이 포함되어 있고, Hibernate가 기본적으로 내장된 구현체로 제공된다. 

 

따라서 별도로 Hibernate를 Gradle이나 Maven 설정에 명시적으로 추가하지 않아도, Hibernate가 JPA 구현체로 자동으로 사용된다.

스프링 부트의 spring-boot-starter-data-jpa는 다음과 같은 주요 구성 요소를 포함한다.

- Hibernate: 가장 널리 사용되는 JPA 구현체로, 스프링 부트는 기본적으로 Hibernate를 사용해 JPA 기능을 제공
- JPA API: Java Persistence API의 클래스와 인터페이스를 포함
- JDBC: 데이터베이스 연결과 실행에 필요한 JDBC 관련 라이브러리가 포함
- Transaction API: 트랜잭션 관리를 위한 API가 포함

 

따라서 JPA starter 패키지에 내장되어 제공되는 Hibernate, 그리고 Hibernate와의 호환이 좋은 EhCache로 2차 캐시를 진행하는 예제 코드를 진행해보도록 하겠다.

 

Hibernate & EhCache

<Hibernate>
1. Hibernate란?
Java 언어를 위한 객체-관계 매핑(Object-Relational Mapping, ORM) 라이브러리 중 하나
Hibernate는 데이터베이스의 테이블을 Java 클래스로, 행을 객체로 매핑하여 개발자가 데이터베이스 작업을 객체 지향적으로 처리할 수 있게 도와줌

2. 특징
- 데이터베이스 독립성
다양한 데이터베이스 시스템을 지원하며, SQL을 직접 작성하지 않고도 데이터베이스 작업을 수행할 수 있음
- 캐싱
1차 캐시와 2차 캐시를 지원하여 성능을 최적화할 수 있음
- 지연 로딩과 즉시 로딩
연관된 객체들을 필요할 때만 로딩하거나 모든 객체를 한 번에 로딩하는 전략을 사용할 수 있음
- 풍부한 쿼리 옵션
HQL(Hibernate Query Language)과 Criteria 쿼리 등 다양한 쿼리 작성 방법을 제공

3. Hibernate가 지원하는 캐시
- 엔터티 캐시
엔터티 단위로 캐시함
식별자(ID)로 엔터티를 조회하거나 컬렉션이 아닌 연관 관계에 있는 엔터티를 조회할 때 사용함
- 컬렉션 캐시
엔터티와 연관된 컬렉션을 캐시함
컬렉션이 엔터티를 담고 있으면 식별자 값만 캐시함
- 쿼리 캐시
쿼리와 파라미터 정보를 키로 사용해서 캐시함
결과가 엔터티면 식별자 값만 캐시함
<EhCache>
1. EhCache란?
EhCache는 자바 기반의 캐시 솔루션으로, 고성능, 풀-피처드(full-featured), 캐시 메모리와 디스크 저장을 지원하는 캐시 라이브러리
빠른 액세스를 위해 자주 사용되는 데이터를 메모리에 저장하므로 데이터베이스 또는 다른 영구 저장소의 부하를 줄이는 데 도움이 됨
2차 캐시에서도 사용될 수 있고, Spring 프레임워크 캐시에서도 사용할 수 있음

2. 특징
- 메모리와 디스크 저장
메모리에 저장되는 캐시와 디스크에 저장되는 캐시 옵션을 제공
- 가용성과 일관성
분산 캐싱 환경에서도 일관성과 가용성을 유지하도록 설계되었음
- 표준 호환성
JCache (JSR-107) 캐시 표준을 구현하여, 표준 API를 통한 캐시 관리와 통합을 지원

3. EhCache의 사용처
- JPA/Hibernate의 2차 캐시
EhCache는 Hibernate의 2차 캐시 구현체로 사용될 수 있음
Hibernate 설정에서 EhCache를 2차 캐시 프로바이더로 지정함으로써, 엔티티 또는 컬렉션의 캐시 전략을 효과적으로 관리할 수 있음
이는 데이터베이스 접근을 줄이고, 세션 간 데이터 공유를 통해 애플리케이션의 성능을 향상시키는 데 도움을 줌
- 스프링 프레임워크 캐시(아래에서 더 자세히 설명할 예정)
스프링의 캐시 추상화를 통해, EhCache는 스프링 애플리케이션에서 메서드 결과를 캐시하는 데 사용될 수 있음
스프링 설정에서 캐시 매니저로 EhCache를 설정함으로써, @Cacheable, @CachePut, @CacheEvict 등의 어노테이션을 사용하여 캐시 동작을 제어할 수 있음
이는 반복적인 데이터 접근을 최소화하고, 애플리케이션의 반응 속도를 개선하는 데 유용함

 

 

Hibernate와 EhCache를 사용한 예제 코드

아래 예시는 스프링부트 프레임워크 위에서 JPA 2차 캐시를 조작하는 예시이다

 

1) Gradle 설정 (build.gradle)

기본적으로는 아래처럼 EhCache만 추가하면 된다.

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa' // Hibernate 포함
    implementation 'javax.cache:cache-api:1.1.1'
    runtimeOnly 'org.ehcache:ehcache:3.9.0'
}

 

특정 Hibernate 버전을 사용하고 싶은 경우 아래처럼 명시적으로 사용할 수 있다.

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    runtimeOnly 'mysql:mysql-connector-java'
    implementation 'org.hibernate:hibernate-core:5.4.32.Final'  // 특정 Hibernate 버전 명시하고 싶은 경우
    implementation 'javax.cache:cache-api:1.1.1'
    implementation 'org.ehcache:ehcache:3.9.0'

    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

 

2) application.yml

spring:
  jpa:
    properties:
      hibernate:
        generate_statistics: true
        
        cache:
          use_second_level_cache: true
          use_query_cache: true
          region:
            factory_class: org.hibernate.cache.jcache.JCacheRegionFactory
      javax:
        cache:
          provider: org.ehcache.jsr107.EhcacheCachingProvider
        persistence:
          sharedCache:
            mode: ALL
2차 캐시 활성화
spring.jpa.properties.hibernate.cache.use_second_level_cache = true

2차 캐시를 처리할 클래스 지정
spring.jpa.properties.hibernate.cache.region.factory_class

하이버네이트가 여러 통계정보를 출력하게 해주는데 캐시 적용 여부를 확인할 수 있음
spring.jpa.properties.hibernate.generate_statistics = true
hibernate true 설정으로, 통계 정보에서 확인할 수 있는 Cache 용어 정리
- L2C puts: 2차 캐시에 데이터 추가
- L2C hits: 2차 캐시의 데이터 사용
- L2C miss: 2차 캐시에 해당 데이터 조회 실패 -> 데이터베이스 접근

2차 캐시 모드 설정
spring.jpa.properties.javax.persistence.sharedCache.mode= (기본값) Enable_selective
- ALL: 모든 엔터티를 캐시
- NONE: 캐시를 사용하지 않음
- ENABLE_SELETIVE: Cacheable(true)로 설정된 엔티티만 캐시를 적용
- DISABLE_SELECTIVE: 모든 엔티티를 캐시하는데 Cacheable(false)만 캐시하지 않음
- UNSPECIFIED: JPA 구현체가 정의한 설정을 따름

 

3) EhCache 설정

EhCache 설정은 Default로 구성되어 있는 것이 있기 때문에 반드시 작성할 필요는 없다.

하지만 각 애플리케이션의 요구사항에 따라 설정을 해야하는 경우 아래 방법을 통해 커스터마이징이 가능하다.

 

xml 설정 파일이나 Config 자바 파일을 사용하여 설정할 수 있다.

여기서는 Config 자바 파일을 통해 설정하는 방식으로 진행해보도록 하겠다.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.CacheManager;
import org.ehcache.Cache;

@Configuration
public class CacheConfig {

    @Bean
    public CacheManager ehCacheManager() {
        CacheManager ehCacheManager = CacheManagerBuilder.newCacheManagerBuilder()
            .withCache("myCache",
                CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class,
                    ResourcePoolsBuilder.heap(100))
                    .build())
            .build(true);
        return ehCacheManager;
    }
}

 

3) Cache 설정

package com.example.demo;

import javax.persistence.*;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

@Entity
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    // Getters and setters are omitted for brevity
}
@Cacheable (JPA)
JPA 스펙에서 제공하는 어노테이션
엔티티의 캐싱 여부를 선언
엔티티의 캐시 가능 여부를 설정
1) 목적
2차 캐시 활성화를 통해 데이터베이스 접근을 최소화하고, 성능을 향상시키는 데 도움을 줌
2) 용도
JPA 스펙에서 제공하는 @Cacheable 어노테이션은 엔티티의 캐싱 가능 여부를 나타냄
이는 엔티티 클래스에 적용되며, 해당 엔티티가 캐시될 수 있는지 여부를 결정함
3) 설정
@Cacheable(true) 또는 @Cacheable(false)로 명시적으로 캐시 가능 여부를 설정할 수 있으며, 기본값은 true
@Cache (Hibernate)
하이버네이트 전용
엔티티 또는 컬렉션의 캐시 전략을 구체적으로 설정
캐시 동시성 관리 전략을 포함하여 캐시 동작을 세부적으로 제어
1) 목적
데이터베이스 로드를 최소화하고, 동시에 여러 세션에서 데이터를 안전하게 사용할 수 있도록 하는 데 중점을 둠
2) 용도
Hibernate의 @Cache 어노테이션은 엔티티나 컬렉션의 캐시 전략을 구체적으로 설정함
이는 @Cacheable과 함께 사용되어 캐시의 동작 방식과 동시성 전략을 정의함
3) 설정
속성 전략이 3가지 있음
a. usage : CacheConcurrencyStrategy를 사용해서 캐시 동시성 전략을 설정
캐시 동시성 전략(CacheConcurrencyStrategy)을 포함해 캐시 동작을 세부적으로 제어할 수 있도록 함
예를 들어 READ_WRITE, NONSTRICT_READ_WRITE, READ_ONLY 등의 전략을 지정할 수 있음
- READ_ONLY: 자주 조회하고 수정 작업을 하지 않는 데이터에 적합
- READ_WRITE: 조회 및 수정 작업을 하는 데이터에 적합
                             Phantom Read 가 발생할 수 있으므로 SERIALIZABLE 격리 수준에서는 사용할 수 없음
- NONSTRICT_READ_WRITE: 거의 수정 작업을 하지 않는 데이터에 적합
b. region : 캐시 지역을 설정
c. include : 연관 객체를 캐시에 포함할지 선택. all, non-lazy 옵션을 선택할 수 있음. 기본값은 all

 

[참고] 스프링 프레임워크에서 제공하는 캐시

스프링 프레임워크에서 제공하는 캐시는 JPA에서 제공하는 캐시와 다른 의미를 가진다.

하지만 @Cacheable 어노테이션의 이름이 JPA에서 제공하는 어노테이션과 이름이 같아 혼동할 수 있기 때문에 여기서 함께 정리하고자 한다.

 

스프링 프레임워크의 Cache 어노테이션

- 스프링의 캐시 추상화를 위한 것

- 데이터베이스나 다른 비싼 비용의 데이터 소스로부터 데이터를 로드하는 작업을 최적화하기 위한 메커니즘을 제공함

- 어노테이션들(@Cacheable, @CachePut, @CacheEvit)은 스프링의 캐시 매니저와 함께 동작하며,

  다양한 백엔드(예: EhCache, Caffeine, Redis 등)를 지원함

- 스프링의 캐시 추상화는 어떠한 특정 캐시 구현에도 종속되지 않으며, 애플리케이션에서 캐시를 쉽게 관리하고 통합할 수 있게 해 줌

import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.CacheEvict;

public class BookRepository {

    @Cacheable(value = "books", key = "#isbn")
    public Book findBookByISBN(String isbn) {
        // 실제 데이터베이스나 다른 소스에서 책 정보 조회
        return new Book(isbn);
    }

    @CachePut(value = "books", key = "#book.isbn")
    public Book updateBook(Book book) {
        // 책 정보 업데이트 로직
        return book;
    }

    @CacheEvict(value = "books", key = "#isbn")
    public void deleteBook(String isbn) {
        // 책 정보 삭제 로직
    }
}
<스프링 프레임워크의 Cache 어노테이션>

@Cacheable

목적: 데이터 조회 시간을 줄이고, 반복적인 데이터 처리 요구를 최소화
사용법: 메소드 선언 위에 어노테이션을 추가하고, 필요한 경우 캐시 이름을 지정
(JPA, Hibernate의 @Cacheable과 다른 어노테이션임)

@CachePut
목적: 데이터를 갱신하거나 추가할 때 캐시도 함께 최신화하여 데이터 일관성을 유지
사용법: 메소드가 반환하는 값을 캐시에 저장하고 싶을 때 사용, 캐시 이름과 키를 지정할 수 있음

@CacheEvict
목적: 데이터 변경이나 조건 충족 시 캐시를 제거하여 오래된 정보가 사용되는 것을 방지
사용법: 캐시에서 항목을 제거할 메소드에 이 어노테이션을 추가
            캐시 이름과 키, 조건 등을 명시할 수 있으며, 캐시 전체를 비우는 옵션도 사용할 수 있음
어노테이션 주요 기능 캐싱 시점 설명
@Cacheable 캐시 조회, 저장 기능 - 캐시 존재 시 '메서드 호출 전 실행'
- 캐시 미 존재 시 '메서드 호출 후 실행'
- 캐시 정보를 메모리 상에 '저장'하거나 '조회' 해오는 기능을 수행할때 사용
@CachePut 캐시 저장 기능 - 캐시 존재 시 ‘메서드 호출 후 실행’
- 캐시 미 존재 시 ‘메서드 호출 후 실행’
- 캐시 정보를 메모리상에 '저장'하며 존재 시 갱신하는 기능을 수행할때 사용
@CacheEvict 캐시 삭제 기능 - beforeInvocation 속성값이 true일때 ‘메서드 호출 전 실행’
- beforeInvocation 속성값이 false일때 ‘메서드 호출 후 실행’
- 캐시 정보를 메모리상에 '삭제'하는 기능을 수행할때 사용
💡 메서드의 호출 전/후 실행은 무슨 차이일까?
- 메서드의 호출 전에 실행 시 DB로부터 데이터를 처리하는 부분에 대해서 줄어들게 된다.
- 반대로 메서드의 호출 후에 실행하는 경우 DB로부터 데이터를 처리하여 가져오는 부분에 대해서 처리하는 부분이 늘어난다.

💡 @CacheEvict의 beforeInvocation 속성이란?
- 캐시의 데이터를 삭제하는데 메서드 호출 전/후에 발생할지에 대해 설정하는 속성을 의미한다.
- 속성의 기본값은 false이며 메서드 실행 전에 캐시에서 데이터를 삭제하여 예외가 발생한다면 캐시에서 데이터가 삭제되지 않는다.
- 이에 따라 예외가 발생할 가능성이 있는 메서드에 대해서 beforeInvocation= “true”를 사용하지 않는 것이 좋다.

💡 @Cacheable과 @CachePut의 다른 점은?
- @Cacheable의 경우는 ‘캐시가 존재하지 않을 경우’ 캐시를 저장하지만 @CachePut의 경우는 ‘캐시의 존재 여부를 떠나서’ 항상 저장 혹은 갱신을 수행한다.

 

그리고 위 설정들을 적용하기 위해 @EnableCaching을 설정 클래스에 붙여줘야 함

@SpringBootApplication
@EnableCaching // 캐시 지원을 활성화하는 어노테이션
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

 

 

2차 캐시와 스프링 프레임워크 캐시의 공통점과 차이점

공통점

두 캐시 모두 애플리케이션의 성능을 향상시키기 위해 데이터를 저장하고, 불필요한 연산이나 데이터베이스 접근을 줄이는 것을 목적으로 합니다.

 

차이점

적용 범위

스프링 캐시는 애플리케이션의 어떤 부분에서든 적용할 수 있는 반면, JPA/Hibernate의 캐시는 엔티티 또는 컬렉션 수준에서 데이터베이스 콘텐츠에 적용됩니다.

기술적 접근

스프링 캐시는 다양한 백엔드를 사용하여 비교적 유연한 캐싱 메커니즘을 제공하는 반면, Hibernate의 캐시는 데이터베이스 작업을 최적화하고 관리하는 데 특화되어 있습니다.

설정과 구성

스프링 캐시는 캐시 이름, 조건 등 다양한 매개변수를 통해 캐시 동작을 세밀하게 제어할 수 있는 반면, JPA/Hibernate의 캐시 설정은 동시성 전략과 캐시 전략에 중점을 둡니다.

 

기준 스프링 프레임워크 캐시 JPA/Hibernate 캐시
공통점 데이터를 임시 저장하여 반복된 데이터베이스 호출 또는 계산을 피하고, 성능을 향상시킴
목적 빈번한 데이터 조회 또는 계산을 최소화하여 응답 시간 단축 및 성능 향상 데이터베이스 로드 감소, 동시성 관리, 전반적인 데이터 접근 성능 향상
설정 및 구성 캐시 이름, 조건, TTL 등을 설정하여 동작 제어 가능 동시성 전략과 캐시 지속성 설정을 통해 데이터 일관성과 성능 보장
적용 범위 애플리케이션 전반의 메서드 결과 캐싱에 사용 데이터베이스 엔티티 또는 컬렉션에 대한 캐싱에 사용
기술적 접근 다양한 캐시 백엔드 지원, 메서드 결과 캐싱으로 유연한 캐시 관리 데이터베이스 작업 최적화에 특화, 2차 캐시를 통한 세션 간 데이터 공유
어노테이션 @Cacheable, @CachePut, @CacheEvict 등을 사용하여 메서드 단위에서 캐시 제어 @Cacheable, @Cache 등을 사용하여 엔티티 또는 컬렉션 단위에서 캐시 전략 설정

 

 

 


출처

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

 

[JPA & Hibernate] First Level Cache & Second Level Cache

영속성 컨텍스트(Persistence Context)의 내부에는 엔티티를 보관하는 저장소가 있는데 이것을 1차 캐시(First Level Cache)라고 부릅니다. 1차 캐시는 트랜잭션이 시작하고 종료할 때까지만 유효합니다.

velog.io

https://junghyungil.tistory.com/203

 

[JPA] 2차 캐시

안녕하세요. 오늘은 2차 캐시에 관해 정리한 내용을 작성해 보도록 하겠습니다. 그리고 2차 캐시에 관해 글을 작성하기에 앞서 우선 캐시와 JPA의 1차 캐시에 관해 잠시 설명해 보도록 하겠습니다

junghyungil.tistory.com

https://develoyummer.tistory.com/87

 

[프로젝트] 2차 캐시의 적용/ 1차캐시와 2차캐시 차이

yata 프로젝트를 진행하며, 프로젝트 내 테이블과 연관관계가 많아지면서 데이터를 조회/검증 하는 데 많은 쿼리가 나가게 되었다. 또, 이러한 쿼리들이 많아지면서 데이터 베이스 서버의 네트워

develoyummer.tistory.com

https://adjh54.tistory.com/166

 

[Java] Spring Boot Cache 이해하고 설정하기 -2 : 사용 및 활용 예시

해당 글에서는 Spring Boot Cache를 이를 이용하는 방법에 대해서 이해를 돕기 위한 글입니다. [참고] Spring Boot Cache의 이론과 환경설정 방법에 대해 궁금하시다면 이전에 작성한 글을 참고하시면 도

adjh54.tistory.com