가자공부하러!

Hibernate(3) - JPA 영속성 컨텍스트, 플러시, 준영속 상태 본문

공부/Java

Hibernate(3) - JPA 영속성 컨텍스트, 플러시, 준영속 상태

오피스엑소더스 2019. 11. 20. 10:50

em : EntityManager

tx : EntityTransaction

 

1. JPA에서 가장 중요한 2가지

  > 객체와 RDB 매핑 설계(정적)

  > 영속성 컨텍스트 : 실제 JPA가 내부에서 어떻게 동작하는가에 대한 내용

 

2. 영속성 컨텍스트란?

  > 엔티티를 영구 저장하는 환경 이라는 뜻

  > 영속성 컨텍스트는 눈에 보이지 않기 때문에 엔티티 매니저를 통해서 영속성 컨텍스트에 접근(엔티티 매니저마다 1:1로 존재)

  > 엔티티의 생명주기

    - 비영속(new) : @Entity 객체만 생성되어있는 상태

    - 영속(managed) : 영속성 컨텍스트에 관리되는 상태 (em.persist(객체); 등의 코드를 통해)

    - 준영속(detached) : 영속성 컨텍스트에 저장되었다가 분리된 상태

    - 삭제(removed) : 삭제된 상태

  > 영속성 컨텍스트의 이점

    - 1차 캐시

      - @Id를 키로갖고 객체를 값으로 가짐

      - 조회하는 경우 1차캐시를 먼저 조회하고 없는 경우 DB에서 조회하고 그 값을 1차 캐시에 저장해서 값 반환

      - 스코프는 엔티티매니저 - 한 트랜잭션에 해당하는 짧은순간

      - 최초로 1차 캐시에 등록된 상태는 스냅샷으로 저장해둠

    - 영속 엔티티의 동일성 보장

      - 1차 캐시로 반복 가능한 읽기 등급의 트랜잭션 격리 수준을 애플리케이션 차원에서 제공

      - 같은 트랜잭션 안에서 ==비교를 보장해준다. 

    - 트랜잭션을 지원하는 쓰기 지연(Transactional Write-Behind)

      - 영속성 컨텍스트에 객체가 저장되는 순간 1차 캐시에 저장되면서 동시에 INSERT 쿼리를 생성해서 쓰기 지연 SQL 저장소에 쌓아둔다.

      - 트랜잭션 커밋이 수행되는 시점에 쓰기 지연 SQL 저장소에 있던 쿼리들이 Flush되고 커밋이 완료됨

      - 쓰기 지연의 존재 이유 : 버퍼링을 통해 최적화 하기 위함 - batch로 묶어서 쿼리 보내기

    - 엔티티 수정 변경 감지(Dirty Checking)

      - 영속상태의 객체의 값이 변경된다면 변경된 내용에 맞게 커밋 시점에 UPDATE쿼리가 수행된다.

      - 방식 : 커밋 시점에 1차캐시의 엔티티와 스냅샷을 비교해서 변경 내용을 감지하고 해당 내용을 쓰기 지연 SQL 저장소에 저장하고 flush한 이후에 커밋한다.

      - 애플리케이션에서 트랜잭션 내 객체상태의 변경이 커밋 시점에 그대로 DB에 반영되기 때문에 조심할 필요가 있다.

    - 지연 로딩(Lazy Loading)

 

3. 플러시란?

  > 영속성 컨텍스트의 변경내용을 DB에 반영하는 역할(동기화)

  > 플러시가 발생하면 무슨 일이 생기나?

    - Dirty Checking

    - 수정된 엔티티 쓰기 지연 SQL 저장소에 등록

    - 쓰기 지연 SQL 저장소의 쿼리를 DB에 전송(커밋 전에 미리 DB에 쿼리를 전송하고 싶을 때 활용 가능)

    - 1차 캐시(엔티티, 스냅샷 등)에는 영향이 없다.

    - 영속성 컨텍스트를 비우지 않는다.

  > 영속성 컨텍스트를 플러시하는 방법

    - 직접 호출(거의 쓸 일 없고 테스트 할 때나 사용) : em.flush();

    - 플러시 자동 호출 : 트랜잭션 커밋, JPQL 쿼리 실행(플러시가 먼저 되고 JPQL쿼리가 실행됨)

  > 플러시 모드 옵션

    - em.setFlushMode(FlushModeType.옵션)

      - FlushModeType.AUTO : 커밋이나 쿼리를 실행할 때 플러시 수행(기본값)

      - FlushModeType.COMMIT : 커밋할 때만 플러시 수행

 

4. 준영속 상태

  > 엔티티가 영속상태로 되는 조건 : em.find(), em.persist()

  > 엔티티를 준영속상태로 만드는 방법 : em.detach(entity), em.clear(), em.close()

 

'공부 > Java' 카테고리의 다른 글

Hibernate(5) - 연관관계 매핑  (0) 2019.11.20
Hibernate(4) - 엔티티 매핑  (0) 2019.11.20
Hibernate(2) - JPA 기본 CRUD 연습  (0) 2019.11.19
Hibernate(1) - ORM? Hibernate?  (0) 2019.11.06
Java_17_Lombok 활용  (0) 2019.07.26
Comments