티스토리 뷰

Spring/JPA

JPA 영속성 관리

snail voyager 2020. 5. 24. 22:34
728x90
반응형

EntityManagerFactory

JPA를 동작시키기 위한 기반 객체를 만들고 DB 커넥션 풀 생성

  • META-INF/persistence.xml 에 있는 정보를 바탕으로 생성

  • 생성 비용이 크기 때문에 한번만 생성하고 공유해서 사용

  • 여러 스레드가 동시에 접근해도 안전. 공유 가능

EntityManager

엔티티를 저장, 수정, 삭제, 조회 등 모든 일을 처리. 가상의 데이터베이스

  • 엔티티 매니저 팩토리에서 엔티티 매니저를 생성. 비용은 거의 들지 않음

  • 여러 스레드가 동시에 접근하면 문제 발생. 공유 금지

  • DB 연결이 꼭 필요한 시점까지 커넥션을 얻지 않음. 트랜잭션을 시작할 때 커넥션을 획득

영속성 컨텍스트 (Persistence Context)

엔티티를 영구 저장하는 환경
엔티티 매니저는 영속성 컨텍스트에 엔티티를 보관하고 관리

  • 영속성 컨텍스트는 엔티티 매니저를 생성할 때 하나 생성

  • 엔티티 매니저를 통해 영속성 컨텍스트에 접근, 관리

엔티티의 생명주기

  • 비영속(new/transient) : 영속성 컨텍스트와 전혀 관계가 없는 상태

  • 영속(managed) : 영속성 컨텍스트에 저장된 상태

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

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

영속성 컨텍스트가 엔티티를 관리하는 장점

  • 1차 캐시 : 영속성 컨텍스트 내부에 Map. 엔티티를 저장

  • 동일성 보장 : 엔티티가 1차 캐시에 없으면 DB를 조회해서 엔티티를 생성, 1차 캐시에 저장

  • 트랜잭션을 지원하는 쓰기 지연 : 쓰기 지연 SQL 저장소에 모아둔 쿼리를 플러시 때 반영

  • 변경 감지 : 최초 상태를 복사한 스냅샷과 엔티티를 비교해서 변경된 엔티티를 찾음

  • 지연 로딩 : 실제 객체 대신 프록시 객체를 로딩해두고
    해당 객체를 사용할 때 영속성 컨텍스트를 통해 데이터를 불러오는 방법

Flush

영속성 컨텍스트의 변경 내용을 DB에 반영

  • 트랜잭션 커밋 시 플러시 자동 호출

  • JPQL 쿼리 실행 시 플러시 자동 호출

  1. 변경 감지가 동작해서 모든 엔티티를 스냅샷과 비교해서 수정된 엔티티를 찾음
  2. 수정 쿼리를 만들어 쓰기 지연 SQL 저장소에 등록
  3. 쓰기 지연 SQL 저장소의 쿼리를 DB에 전송

준영속 상태(detached)

영속 상태였다가 분리되어 영속성 컨텍스트가 관리하지 않는 상태

  • em.detach(entity), em.clear(), em.close()

  • 1차 캐시부터 쓰기 지연 SQL 저장소까지 모든 정보 제거

  • 거의 비영속 상태

  • 식별자 값을 가지고 있음 : 이미 한 번 영속 상태였으므로 반드시 식별자 값 존재

  • 지연 로딩 불가

  • merge(entity) 메소드는 준영속 상태의 엔티티를 받아서 새로운 영속 상태의 엔티티를 반환

  • 병합은 파라미터로 넘어온 엔티티의 식별자 값으로 1차 캐시 조회하고 없으면 DB에서 조회.
    그래도 없으면 새로운 엔티티를 생성해서 병합

728x90
반응형

'Spring > JPA' 카테고리의 다른 글

JPA (Java Persistence API)  (0) 2020.05.24
반응형
300x250