영속성 관리 - 내부 동작 방식

유동우·2023년 7월 24일
0
post-thumbnail

영속성 컨텍스트 1

JPA에서 가장 중요한 2가지

  • 객체와 관계형 데이터베이스 매핑하기 (Object Relational Mapping)
  • 영속성 컨테스트

영속성 컨섹스트

  • JPA를 이해하기 위한 가장 중요한 용어이다
  • "엔티티를 영구 저장하는 환경"
EntityManager.persist(entity);
// DB에 저장하는게 아니라 entity를 영속성 컨텍스트라는 곳에 저장하는 것이다.
// 영속성 컨텍스트는 논리적 개념으로 눈에 보이지 않기 때문에, EM을 통해서 접근한다.

엔티티의 생명주기

// 비영속
   Member member = new Member();
   member.setId(100L);
   member.setName("HelloJPA");

// 영속
   em.persist(member); // persist가 아닌 commit 하기 전에 쿼리를 날린다.

영속성 컨텍스트 2

영속 컨텍스트의 이점

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

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

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

//find("member2")의 경우 1차캐시에 없기 때문에 DB에서 조회하여 1차캐시에 저장 후 반환
//-> 1차 캐시에 저장 ? = 영속 상태로 등록
  1. 동일성 보장
Member a = em.find(Member.class, "member1");
Member b = em.find(Member.class, "member1");

System.out.println(a == b); //동일성 비교 true

// 1차 캐시로 반복 가능한 읽기(REPEATABLE READ) 등급의 트랜잭션 격리 수준을 
// 데이터베이스가 아닌 애플리케이션 차원에서 제공
-> 쉽게 생각하면, 동일한 트랜잭션에서 실행하면 == 비교시 true
  1. 트랜잭션을 지원하는 쓰기지연
em.persist(member1);
em.persist(member2);

System.out.println("=======================");
            
tx.commit();

버퍼링을 모아서 write 하는 이점을 얻을 수 있다

  1. 변경 감지
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin(); // [트랜잭션] 시작

// 영속 엔티티 조회
Member memberA = em.find(Member.class, "memberA");

// 영속 엔티티 데이터 수정
memberA.setUsername("hi");
memberA.setAge(10);

//em.update(member) 이런 코드가 있어야 하지 않을까?

transaction.commit(); // [트랜잭션] 커밋
스냅샷과 비교하여 새로운 쿼리를 생성하여 UPDATE 한다
(값이 이전과 같거나 달라도 모두 쿼리를 전달, if 문 같은것을 사용 할 필요 x)
  1. 지연 로딩
    ???

플러시

쌓아놨던 SQL 문을 DB에 날린다
즉, 영속성 컨텍스트의 변경 내역들을 DB에 전달한다

  • 변경감지
  • 수정된 엔티티 쓰기 지연 SQL 저장소에 등록
  • 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송

(flush가 발생한다고 해서 DB 트랜잭션에 커밋되는것은 아니다)

플러시 방법 (알아만 놓기)

  • em.flush() - 직접 호출
  • 트랜잭션 커밋 - 플러시 자동 호출
  • JPQL 쿼리 실행 - 플러시 자동 호출

플러시는 1차캐시는 건드리지 않고, (영속성 컨텍스트를 비우지 않음) (1차캐시에 올라간 상태 = 영속 상태)
쓰기 지연 SQL 저장소에 있는것과 변경 감지된 UPDATE 쿼리들이 쌓인것들을 DB에 반영하는 과정이다.

-> 트랜잭션이라는 작업단위가 중요하기 때문에 커밋 직전에만 동기화를 하면 된다

준영속 상태

지금 이해하기는 쉽지않고 실전에서 (웹 애플리케이션 개발)

  • em.detach(entity)
    특정 엔티티만 준영속 상태로 전환
  • em.clear()
    영속성 컨텍스트를 완전히 초기화
  • em.close()
    영속성 컨텍스트를 종료

Reference
김영한 님 - 자바 ORM 표준 JPA 프로그래밍 - 기본편

profile
효율적이고 꾸준하게

0개의 댓글