영속성 컨텍스트의 이점

1) 1차 캐시

2) 동일성(identity) 보장

3) 트랜잭션을 지원하는 쓰기 지연 (transactional write-behind)

4) 변경 감지 (Dirty Checking)

5) 지연 로딩


엔티티 조회, 1차 캐시

학습4-1

//객체를 생성한 상태(비영속)
Member member = new Member();
member.setId("멤버1");
member.setUserName("회원1");

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

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

1차캐시에저장됨


  • 키가 pk로 등록한 값이 되고 value가 객체가 된다.

1차 캐시에서의 조회

  • DB를 찾아보는게 아니라 캐시를 조회먼저해서 가져온다.

데이터 베이스에서의 조회

학습4-2

  1. find(“member2”) - > 1차 캐시에 없음
  2. DB 조회
  3. 1차 캐시에 저장을 한다.
  4. member2 반환
  5. 이후 member2를 조회하면 1차캐시에서 가져온다

하지만, 엔티티 매니저는 DB 트랜잭션 단위로 만들고 트랜잭션이 끝나면 종료시키는데 고객의 요청이 끝나면 지우기 때문에 1차캐시도 이때 날라간다.

1차 캐시 저장되고, 그 이후 조회를 하기때문에 select 쿼리가 로그로 남지 않았다.


영속 엔티티의 동일성 보장

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

            //영속
            System.out.println("=====BEFORE=====");
            em.persist(member);
            System.out.println("=====AFTER=====");

            Member findMember1 = em.find(Member.class, 101L);
            Member findMember2 = em.find(Member.class, 101L);
            
            System.out.println(findMember1 == findMember2) // true 반환함! 

            tx.commit();

true 이유 : 1차캐시가 있기때문에 반복가능한 읽기를 애플리케이션 차원에서 제공한다.


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

EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();

//엔티티 매니저는 데이터 변경시 트랜잭션을 시작해야한다.
 transaction.begin(); // 트랜잭션 시작

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

 //커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다.
 transaction.commit(); // 트랜잭션 커밋

학습4-3

  • 멤버A가 일단 1차 캐시에 들어감과 동시에 JPA가 엔티티를 분석해서 SQL 생성하고 쓰기지연 SQL 저장소에 저장해둠
  • 멤버B도 똑같이 동작하고 쓰기 지연 SQL 저장소에 쌓아둔다.
  • 트랜잭션을 커밋하는 시점에 flush가 되면서 날라간다.


변경 감지

변경감지

값만 바꾸고, JPA에게 업데이트 쿼리를 날려달라고 한게없는데 변경된 것을 확인 할 수있다.

변경감지 동작

4-4

    1. flush()
    1. 엔티티와 스냅샷 (내가 값을 읽어온 최초시점의 상태를 떠놓는것 )과 비교
    1. Update SQL 생성
    1. flush 후 commit 됨


Flush

영속성 컨텍스트의 변경내용을 데이터베이스에 반영하는 것

플러시 발생시

  • 변경감지 일어난다.
  • 수정된 엔티티 쓰기 지연 SQL 저장소에 등록
  • 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송 (등록, 수정, 삭제 쿼리)

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

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


😄 참고 : 인프런 김영한님의 JPA 기본 강의 및 교재 , 블로그

🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우 언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄

개인메모

태그:

카테고리:

업데이트: