본문 바로가기

Spring

영속성 컨텍스트의 이점

728x90

1차 캐시

private static void cache(EntityManagerFactory emf){
        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();

        try{
            Member member = new Member("member1","1");

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

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

            tx.commit();

        }catch (Exception e){
            tx.rollback();
        }finally {
            em.close();
        }
    }

영속성 콘텍스트의 1차 캐시에서 findMember를 조회해 오기 때문에 조회해 오는 query는 발생하지 않고 insert query만 발생한다.

 

영속엔티티의 동일성 보장

private static void identity(EntityManagerFactory emf){
        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();

        try{
            Member member1 = em.find(Member.class, "member1");
            Member member2 = em.find(Member.class,"member1");
            System.out.println("result = " + (member1==member2));

            tx.commit();

        }catch (Exception e){
            tx.rollback();
        }finally {
            em.close();
        }

    }

 

member1을 데이터베이스에서 조회하여 1차캐시에 캐싱하기 때문에 member1과 기본키를 가지는 member2를 조회할 때는 쿼리가 날아가지 않고 1차 캐시 안에서 조회해 오기 때문에 member1과 member2는 동일한 엔티티임을 확인할 수 있다.

 

트랜잭션을 지원하는 쓰기 지연

private static void writeDelay(EntityManagerFactory emf){
        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();

        try{
            Member memberA = new Member("memberA","A");
            System.out.println("delay 확인");
            Member memberB = new Member("memberB","B");

            em.persist(memberA);
            em.persist(memberB);

            tx.commit(); // 커밋하는 순간 데이터베이스에 insert sql을 보낸다.

        }catch (Exception e){
            tx.rollback();
        }finally {
            em.close();
        }

    }

memberA와 memberB가 persist()할 때 쿼리가 날아가지 않고  트랜잭션이 commit() 될 때 flush가 되면서 insert query 2개 날아가는 것을 볼 수 있다.

 

변경감지

private static void changeDetection(EntityManagerFactory emf){
        EntityManager em = emf.createEntityManager();

        EntityTransaction tx = em.getTransaction();
        tx.begin();

        try{
            Member findMember = em.find(Member.class, "memberA");
            findMember.setName("memberC");

            tx.commit();

        }catch (Exception e){
            tx.rollback();
        }finally {
            em.close();
        }

    }

변경 전 데이터베이스
변경 후 데이터베이스

update를 하는 코드가 없어도 flush()후 엔티티와 스냅샷을 비교하여 변경된 부분이 있을 시 UPDATE SQL이 생성되어 DB에 flush 된다.

728x90

'Spring' 카테고리의 다른 글

연관관계 매핑  (0) 2023.03.20
Entity Mapping  (0) 2023.03.18
타임리프 문법  (0) 2023.03.15
RedirectAttributes  (0) 2023.03.15
PRG  (0) 2023.03.15