시냅스

JPA 영속성 컨텍스트 정리 본문

Java, Spring/JPA

JPA 영속성 컨텍스트 정리

ted k 2022. 9. 16. 21:06

영속성 컨텍스트 persistence context

  • 엔티티를 영구 저장하는 환경
  • 영속성 컨텍스트는 논리적인 개념으로 눈에 보이지 않는다.
  • 엔티티 매니저를 통해 영속성 컨텍스트에 접근한다.
  • J2SE(일반 자바 어플리케이션 개발 툴)
    • EntityManger 와 영속성 컨텍스트는 1:1 의 관계이다.
  • J2EE (서버용 자바 어플리케이션 개발 툴), Spring 과 같은 컨테이너 환경
    • EntityManager와 영속성 컨텍스트는 N:1 의 관계이다.

 

엔티티의 생명주기

  • 비영속 (new/transient)
    • 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
Member member = new Member();
member.setId("member1");
member.setUsername("회원1");

 

  • 영속 (managed)
    • 영속성 컨텍스트에 관리되는 상태
// 객체를 생성한 상태 (비영속)
Member member = new Member();
member.setId("member1");
member.setUsername("회원1");

EntityManger em = emf.createEntityManager();
em.getTransaction().begin();

// 객체를 저장한 상태 (영속)
em.persist(member);

 

  • 준영속 (detached)
    • 영속성 컨텍스트에 저장되었다가 분리된 상태
    • 영속성 컨텍스트가 제공하는 기능을 사용하지 못한다.
// 회원 엔티티를 영속성 컨텍스트에서 분리, 준영속 상태
em.detach(member)

 

  • 삭제 (removed)
    • 삭제된 상태
// 객체를 삭제한 상태 (삭제)
em.remove(member);

 

영속성 컨텍스트의 이점

  • 1차 캐시

Member member = new Member();
member.setId("member1");
member.setUsername("회원1");

// 1차 캐시에 저장됨
em.persist(member);

// 1차 캐시에서 조회
Member findMember = em.find(Member.class, "member1");

// 만약 DB에 있다면, DB에서 조회해서 1차 캐시에 저장하여 반환한다.
Member findMember2 = em.find(Member.class, "member2");
  • 동일성(identity) 보장
    • 1차 캐시로 반복 가능한 읽기 (REPEATABLE READ) 등급의 트랜잭션 격리 수준을 데이터베이스가 아닌 애플리케이션 차원에서 제공
Member a = em.find(Member.class, "member1");
Member b = em.find(Member.class, "member1");

a == b // 동일성 비교 true
  • 트랜잭션을 지원하는 쓰기 지연 (transactional write-behind)

EntityManger em = emf.createEntityManager();
em.getTransaction().begin(); // 트랜잭션 시작

em.persist(memberA);
em.persist(memberB);
// 여기까지 insert sql 을 데이터베이스에 보내지 않는다.

// 커밋하는 순간 데이터베이스에 insert sql을 보낸다
commit(); // 트랜잭션 커밋
  • 변경 감지 (Dirty Checking)

EntityManger em = emf.createEntityManager();
em.getTransaction().begin(); // 트랜잭션 시작

// 영속 엔티티 조회
Member memberA = em.find(Member.class, "memberA");
// 영속 엔티티 데이터 수정
memberA.setUsername("hi");

// em.update(member) 과 같은 코드가 없어도, 
// 1차 캐시 내부 스냅샷과 비교하여 변경사항이 있다면 update를 실행한다.

commit(); // 트랜잭션 커밋
  • 지연 로딩 (Lazy Loading)
    • 연관관계에서 자세하게 설명한다.
  • 플러시 flush
    • 영속성 컨텍스트의 변경내용을 데이터베이스에 반영
    • 변경 감지
    • 수정된 엔티티 쓰기 지연 SQL 저장소에 등록
    • 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송
    • flush가 호출되는 조건
      • em.flush - 직접 호출
      • 트랜잭션 커밋 - 플러시 자동 호출
      • jpql 쿼리 실행 - 플러시 자동 호출
      • 만약 엔티티를 persist로 저장하고 jpql 로 select 조회했을 때 플러시가 실행되지 않는다면 조회할 수 없다. (아직 커밋으로 db에 저장되지 않았기 때문에) 하여 jpql 실행 전에 flush로 db와 동기화한다.
    • 플러시는 영속성 컨텍스트를 비우지 않는다.
    • 영속성 컨텍스트의 변경 내용을 데이터베이스에 동기화 한다.

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

JPA 상속관계 매핑 정리  (0) 2022.09.17
JPA 연관관계 정리  (0) 2022.09.16
JPA 엔티티 매핑 정리  (0) 2022.09.16
Spring Data JPA 정리  (0) 2022.09.03
Spring JPA 기본 사용법 정리  (0) 2022.09.03
Comments