ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • #JPA-5 영속성 컨텍스트(2)
    JPA 2021. 2. 15. 16:52

    [출처] 인프런 김영한 강사님 -자바 ORM 표준 JPA 프로그래밍 기본

     

    1. 영속성 컨텍스트의 이점

    • 1차 캐시

    • 동일성(identity) 보장

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

    • 변경 감지(Dirty Checking)

    • 지연 로딩(Lazy Loading)

     

    2. 엔티티 조회, 1차 캐시

    1차 캐시

    영속성컨텍스트는 내부에 1차캐시를 들고 있다. 

    @id(PK) :  key

    Entity : value

    3-1. 1차 캐시에서 조회

    1차 캐시에서 조회

    em.find를 하게 되면 먼저 DB에 접근하지 않고 1차 캐시를 찾는다.

    만약 MEMBER1을 조회할 경우 1차캐시에 MEMBER1이 있기때문에 캐시에 있는 값을 그대로 조회해 온다.

     

     

    1차 캐시 알아보기 1 - 최초 저장 후 조회

            try{
                //비영속
                Member member = new Member();
                member.setId(101L);
                member.setName("HelloJPA");
    
                //영속
                System.out.println("=== BEFORE ===");
                em.persist(member);
                System.out.println("=== AFTER ===");
    
                Member findMember = em.find(Member.class, 101L);
    
                System.out.println("findMember.id = "+findMember.getId());
                System.out.println("findMember.name = "+findMember.getName());
    
                tx.commit();
            } catch (Exception e){
                tx.rollback();
            }finally {
                em.close(); 
            }

    find를 했는데 왜 select 쿼리가 나오지 않는가? persist할때 값을 저장하고 1차 캐시에 저장했기 때문이다.

     

    1차 캐시 알아보기 2 - 조회 후 같은 KEY 다시 조회

    Member findMember1 = em.find(Member.class, 101L);
    Member findMember2 = em.find(Member.class, 101L);

    최초 조회만 DB에서 가져오고 그 다음 조회는 1차 캐시에 저장하기 때문에 다시 SELECT QUERY가 날라가지 않는다.

     

    3-2. 데이터베이스에서 조회

    DB에서 조회

    만약 MEMBER2을 조회할 경우 1차캐시에 없으면 DB에서  MEMBER2를 조회하고 1차캐시에 저장한 후 MEBER2를 반환

     

    3-3. 1차 캐시 영역

    EM은 DB Transcation 단위로 보통 만들어 진다. db transaction이 끝나게 되면 영속성 컨텍스트를 지우고 1차캐시가 날라간다. 1차캐시는 찰라의 순간에서만 이득이기 때문에 여러명이 공유해서 사용하는 캐시가아니다.

    Applicaiton 전체를 공유하는것은 2차 캐시이다.

    다시말해서 1차캐시의 큰 성능의 이점은 없다. 하지만 비지니스 로직이 엄청 복잡한 경우에는 이점이 있을 수 있다.

    4. 영속 엔티티의 동일성 보장

    1차 캐시로 반복 가능한 읽기(REPEATABLE READ) 등급의 트랜잭 션 격리 수준을

    데이터베이스가 아닌 애플리케이션 차원에서 제공

    Member findMember1 = em.find(Member.class, 101L);
    Member findMember2 = em.find(Member.class, 101L);
    
    System.out.println("result = "+ (findMember1 == findMember2));

     

    결과를 보면 true가 나온다 JPA가 영속 Entity의 동일성을 보장해준다. (1차 캐시를 통해서)

    마치 JAVA COLLCETION 에서 똑같은 reference가 있는 객체를 꺼내면 똑같이 인식하듯 이것을 가능하게 해준다.

     

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

    em.persist(memberA);

    persist가 일어나면 memberA가 1차 캐시에 들어가면서 JPA가 Enitity를 분석해 INSERT 쿼리를 생성해서 쓰기지연 SQL 저장소에 저장.

    em.persist(memberB);

    persist가 일어나면 memberB가 1차 캐시에 들어가면서 JPA가 Enitity를 분석해 INSERT 쿼리를 생성해서 쓰기지연 SQL 저장소에 저장.

    transaction.commit();

    transcation commit하는 시점에 쓰기 지연 SQL  저장소에 있던 애들이 FLUSH가 되고, 실제 DB에 commit된다.

     

    6. 엔티티 수정 변경 감지

    엔티티 수정 변경 감지

     

    변경 감지 (Dirty Checking)

    여기서 말하는 스냅샷은 값을 읽어온 최초 서점의 상태.(최초로 영속성 컨텍스트의 1차캐시에 들어온 상태)

    memberA가 commit되는 시점에 내부적으로 JPA가 Entity와 snapShot 을 비교한다.

    바뀌어 있으면 update를 쓰기 지연 sql 저장소에 쌓는다. 그리고 UPDATE쿼리를 DB에 반영하고 commit한다.

    7. 엔티티 삭제

    update와 매커니즘은 같고 transaction commit시점에 delete가 나간다.

     

    댓글

Designed by Tistory.