notepad

[JPA-BASIC] 영속성 관리 본문

JPA

[JPA-BASIC] 영속성 관리

likewise_ 2020. 7. 16. 11:43

인프런 김영한 강사님의 자바 ORM 표준 JPA 프로그래밍 - 기본편 내용 정리

영속성 컨텍스트

  • ‘엔티티를 영구 저장하는 환경’
  • em.persist(entity); 를 통해 영속화
  • 영속성 컨텍스트는 논리적인 개념으로 엔티티 매니저를 통해서 영속성 컨텍스트에 접근한다.
  • 1차 캐시(식별키, 엔티티, 스냅샷 저장) 과 쓰기 지연용 SQL저장소로 구성

엔티티 매니저 팩토리와 엔티티 매니저

  • 웹 애플리케이션은 하나의 엔티티 매니저 팩토리(emf) 를 가지고, 요청이 일어날 때마다 emf에서 엔티티 매니저를 생성한다. 요청에 의해 생성된 엔티티 매니저는 디비 커넥션을 사용하여 DB 데이터에 접근한다.
  • 엔티티 매니저는 DB의 트랜잭션 단위로 만들고 소멸된다
  • Persistence를 통해 EntityManagerFactory생성 -> EntityManagerFactory 로 EntityManager 생성 -> EntityTransaction 으로 트랜잭션 관리 -> em.persist(entity) 를 통해 엔티티 영속화
  • 엔티티의 생명 주기
    • 비영속(new/transient) : 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
    • 영속(managed) : 영속성 컨텍스트에 관리되는 상태
    • 준영속(detached : 분리된) : 영속성 컨텍스트에 저장되었다가 분리된 상태
    • 삭제(removed)

영속성 컨텍스트의 이점

  • 1차 캐시
  • 동일성(identity) 보장
  • 트랜잭션을 지원하는 쓰기 지연(transactional write-behind)
  • 변경 감지(Dirty Checking)
  • 지연 로딩(Lazy Loading)

1차 캐시

  • 한 트랜잭션 안에서 캐싱 발생
  • 트랜잭션이 소멸되면 1차 캐시도 끝난다.
  • 사실 그렇게 큰 성능 이점이 없다. -> 비즈니스가 복잡할 때 도움이 된다. / 성능 보다는 매커니즘 상의 이점이 있다.

영속 엔티티의 동일성 보장

  • 똑같은 데이터를 조회 한 후 == 비교시 같다고 나옴 (식별자가 똑같은 경우)
  • 1차 캐시로 반복 가능한 읽기 등급의 트랜잭션 격리 수준을 데이터베이스가 아닌 애플리케이션 차원에서 제공

엔티티 등록 시 트랜잭션을 지원하는 쓰기 지연 제공

  • 영속컨텍스트(entityManager) 에는 1차 캐시와 쓰기 지연 SQL저장소가 존재한다.

  • 엔티티 영속화 발생 시(em.persist(entity) 1차 캐시에 id, entity 값을 저장하고, 쓰기 지연 SQL 저장소에는 생성된 쿼리를 저장한다.

  • 트랜잭션을 커밋하는 시점에 [쓰기지연 SQL저장소]가 flush되고 쿼리가 디비로 날아가면 디비 트랜잭션이 커밋된다.

    버퍼링 기능을 사용 할 수 있다 : 최적화 여지가 있다. | jdbc batch 기능 등

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

  • 스냅샷 : 값을 읽어온 최초 시점의 상태를 스냅샷으로 떠 둠 | 처음 영속성 컨텍스트에 들어온 상태
  • flush가 발생했을때 1차캐시의 엔티티와 스냅샷을 비교하여 변경이 감지될 경우 update쿼리를 쓰기지연저장소에 추가한다.

em.find() 는 별도의 매커니즘 없이 JPA가 jdbc를 통해 직접 SQL을 날리고 데이터를 조회한다.

플러시

  • 영속성 컨텍스트의 변경내용을 데이터베이스에 반영
  • 플러시 발생 : 트랜잭션 커밋, 변경 감지, JPQL 쿼리 실행 시 발생.
  • 변경감지 -> 수정된 엔티티 쓰기 지연 SQL 저장소에 등록 -> 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송(등록, 수정, 삭제 쿼리) -> flush를 했다고 DB가 커밋되는 것은 아니다. tx.commit()을 해 줘야 커밋이다. | update가 되면 스냅샷과 엔티티 값이 같아 진다
  • 플러시를 해도 1차 캐시는 유지된다.
    • 플러시모드옵션 : AUTO, COMMIT이 있는데 되도록 건드리지 말고 AUTO(default) 를 쓰자

플러시는!

  • 영속성 컨텍스트를 비우지 않는다
  • 영속성 컨텍스트의 변경 내용을 데이터베이스에 동기화
  • 트랜잭션이라는 작업 단위가 중요 -> 커밋 직전에만 동기화하면 됨

*** 궁금한 점

  • JPQL 쿼리 실행을 통한 flush 상태일 때 이전의 persist 데이터들은 아직 DB커밋이 안된 상태가 맞는지? => 커밋 안된 상태가 맞음. 플러시가 되더라도 저장은 결국 커밋이 이루어져야 변경된다

  • 플러시 이 후 영속성 컨텍스트 내부의 쓰기 지연 SQL저장소는 비워지는게 아닌지? -> 비워지는게 맞음 , 1차 캐시만 유지된다.

  • 쓰기 지연의 이점 : 네트워크를 한번만 타게 할 수 있다.


JPA 프로젝트 설정/영속성 관리 - 실습

  1. release version 5 not supported 에러

    intelliJ 설정 :

    • Preferences > Java Compiler에 target byte code version 변경
    • Project Structure > Language level 변경
  2. Entity 추가시 식별자 @Id 가 없으면 에러가 난다

  3. Entity를 default Package에 추가 후 JPQL 사용 시 unexpected token error 발생 -> 패키지 추가하여 사용

'JPA' 카테고리의 다른 글

[JPA 활용1] 요약  (0) 2020.08.07
[JPA 활용2] 기본~ 고급 요약  (0) 2020.08.07
[JPA 활용2] 고급 - 지연 로딩과 조회 성능 최적화  (0) 2020.08.05
[JPA 활용2] API 개발 기본  (0) 2020.08.03
[JPA-BASIC] 엔티티 매핑  (0) 2020.07.17
Comments