PlayData 백엔드 부트캠프 정리

1차 캐시와 2차 캐시의 차이와 스프링부트에서 이용

효건 2025. 1. 8. 10:16

1. 1차 캐시

    가. 정의 :EntityManager에서 제공하는 캐시로 같은 트랜잭션 안에서만 동작하는 세션 범위 캐시 
    나. 특징 

         1) 트래젝션 범위 : 같은 EntityManger안에서만 동작하며 트랜젝션이 종료되면 1차캐시는 소멸한다.

         2) 자동으로 활성화 : 별도의 설정없이 JPA가 자동으로 관리

         3) 캐시 저장 기준 : 같은 트랜젝션 내에서 동일한 엔티티를 다시 조회하면 데이터 베이스를 다시 조회하지 않고 1차 캐시 반환

         4) 용도 : 데이터 베이스의 조회 비용을 줄임, 엔티티의 중복생성을 방지

 

 

2. 2차 캐시

    가. 정의 :EntityManagerFactory수준에서 관리되는 캐시로 인스턴스와 트랜젝션 간에 공유 가능한 캐시
    나. 특징 

         1) 범위 : 애플리케이션 범위에서 동작되며 모든 entitymanger가 공유 

         2) 설정 필요: Hibernate, Ehcache, Infinispan 같은ㄴ 구현체를 통해 설정해야 활성화

         3) 캐시 저장 기준 : 영속성 컨텍스트에서 엔티티가 플러시되면 저장 2차캐시를 사용하면 조회를 스킵함.

         4) 용도 :자주 사용되나 변경이 적은 곳에서 캐싱하여 성능을 최적화 조회성능향상및 데이터베이스 부하 감소

 

데이터가 조회를 요청하면 1차캐시에서 검사 -> 2차캐시검사 -> 데이터 조회의 절차를 거친다.

 

 ※ EntityManger 정리 

      1) 역할

           가) 영속성 컨텍스트 관리 -> 생명주기를 관리하며 엔티티의 상태를 추적

           나) 데이터베이스 작업 실행 -> CRUD 작업을 실행

           다) 트랜젝션 관리 -> 데이터베이스 트랜젝션 내에서 엔티티와의 상호작용을 수행 -> 개발자가 지정할 수있으나

                 대부분 JPA가 자동으로 실행

           라) 1차캐시 제공 동일 트랜젝션 앤에서 성능을 최적화 

       2) 주요 메서드

           가) find : 데이터 베이스에서 기본키로 엔티티를 조회함. 단, 영속성 컨텍스트에 엔티티가 있으면 조회를 생략

           나) persist : 엔티티를 영속상태로 전환 트랜젝션 커밋시 데이터 베이스에 저장 

           다) merge : 준영속 상태나 비영속 상태의 엔티티를 영속상태로 병합 -> 기존데이터는 업데이트 되며 데이터베이스에 반영

           라) remove : 영속상태에 있는 엔티티를 삭제

           마)  createQusey: 데이터베이스 쿼리를 실행

           바) flush : 영속성 컨텍스트에 있는 변경 사항을 데이터베이스에 강제로 반영합니다(즉시반영)

           사) clear : 영속성 컨텍스트를 비워서 모든 엔티티를 준영속 상태로 만듭니다.(초기화)

           아) refresh : 영속성 컨텍스트에서 관리되는 엔티티의 상태를 데이터베이스로부터 다시 읽어옵니다.(갱신)

 

영속성 컨텍스트와의 관계

영속성 컨텍스트(Persistence Context)

  • 영속성 컨텍스트는 JPA 엔티티를 관리하는 1차 캐시.
  • EntityManager는 이 영속성 컨텍스트를 관리합니다.

상태 변화

  1. 비영속 상태: 엔티티가 JPA와 관련이 없는 상태.
  2. 영속 상태: 엔티티가 영속성 컨텍스트에서 관리되는 상태.
  3. 준영속 상태: 영속성 컨텍스트에서 분리된 상태.
  4. 삭제 상태: 엔티티가 영속성 컨텍스트에서 제거되어 데이터베이스에서 삭제 대기 상태.

 ※ 트랜젝션 정리

      1) 개념

           가) AICD 속성

                ① 원자성 : 트랜젝션 내모든 작업이 성공해야만 모두 반영, 하나라도 실패시 롤백

                ② 일관성 : 트랜잭션 전후에 데이터베이스 상태가 일관성 유지

                ③ 격리성 : 트랜젝션 간 동시 실행시 간섭하지 않음

                ④ 내구성 : 트랜젝션이 커밋되면 데이터는 영구적 저장

           나) 트랜젝션 경계

                ① 트랜젝션 시작

                ② 작업수행

                ③ 작업 완료 후 커밋 or 롤백

 

3. 1차 캐시와 2차 캐시의 이용 

    가. 1차캐시 

      1) 자동으로 적용됨 . 그러나 커스텀을 하고싶다면 한메서드를 선언하고 @Transaction 어노테이션을 이용하면됨

    나. 2차캐시

         스프링 캐시과 여러가지 데이터베이스를 이용해서 할수있음. 대표적으로 redis ,hibernate, ehcaher가있음.

        이를 이용하기 위해서는 먼저 gradle 또는 maven 의존성을 추가해야한다. 

1) hibernate사용시

dependencies {
    implementation 'org.hibernate:hibernate-core:5.x.x' // Hibernate
    implementation 'org.ehcache:ehcache:3.x.x'         // Ehcache
}

 

이후 application.yaml 파일에 추가해야하는데 spring 하위 jpa하위에 작성해야 한다. 

spring:
  jpa:
    properties:
      hibernate.cache.use_second_level_cache: true       # 2차 캐시 활성화
      hibernate.cache.region.factory_class: org.hibernate.cache.jcache.JCacheRegionFactory
      javax.cache.provider: org.ehcache.jsr107.EhcacheCachingProvider

 

그런 다음에 entity에 

@Entity @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) // 읽기/쓰기 캐시 전략 어노테이션을 사용한다.

 

옵션 종류로는 

  • READ_ONLY: 읽기 전용 데이터에 사용. 캐시 성능이 높음.
  • NONSTRICT_READ_WRITE: 약간의 데이터 불일치를 허용.
  • READ_WRITE: 읽기와 쓰기 작업 모두 보장.
  • TRANSACTIONAL: 트랜잭션 수준의 캐시(잘 사용되지 않음)

2) Ehache 설정 

resource 폴더 내부에 ehcache.xml 을 만들고 내부에 

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://www.ehcache.org/v3"
        xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core.xsd">
    <cache alias="productCache">
        <expiry>
            <ttl unit="seconds">3600</ttl> <!-- 캐시 데이터 유효 시간: 1시간 -->
        </expiry>
        <heap unit="entries">1000</heap> <!-- 최대 캐시 엔트리 수 -->
        <disk persistent="false" /> <!-- 디스크 사용 여부 -->
    </cache>
</config>

을 작성한다.

 

private final Entity Manger  을 주입하고 이에 따라 메서드를 이용하여 추가하고 변경하는 로직에 반영한다. 

끝.