본문 바로가기

강의/자바 ORM 표준 JPA

JPA, 영속성 컨텍스트의 이점 (트랜잭션을 지원하는 쓰기 지연)

영속성 컨텍스트를 사용하면 5가지의 이점을 얻을 수 있다.

• 1차 캐시

• 동일성(identity) 보장

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

• 변경 감지(Dirty Checking)

• 지연 로딩(Lazy Loading)

 

1차 캐시에서 설명했던 것과 유사한 부분이다.

트랜잭션을 지원하는 쓰기 지연이란 알기 쉽게 말해서 query는 commit하는 시점에 날린다는 것이다.

 

memberA와 memberB를 1차 캐시에 저장하는 persist 명령어를 사용하면, 쓰기 지연 SQL 저장소에 query문을 임시로 저장한다.

 

 

commit 하는 시점에 쓰기 지연 SQL 저장소에 저장되어 있는 query들을 날려버린다.

 

commit 하는 시점에 query를 모아서 날리는 것에는 어떤 이점이 있을까?

최적화를 할 수 있다는 장점이 있다.

persistence.xml 파일에 
<property name="hibernate.jdbc.batch_size" value="10"/>
이라는 옵션을 주게되면 쿼리를 각각 날리는 것이 아니라 한번에 날려버릴 수 있어서,
조금 더 최적화하여 쿼리를 날려줄 수 있다.

 

 

위 과정을 코드로 확인해보자.


member1, member2를 persist로 1차 캐시에 저장하고, commit을 하는 명령어다.

persist와 commit 명령어 사이에는 === 으로 구분선을 출력하였다.

우리가 배운 것과 동일하다면 query문은 == 구분선이 출력된 이후에 날아갈 것이다.

 

package hellojpa;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

public class JpaMain {

    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

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

        // code
        Member member1 = new Member(150L, "A");
        Member member2 = new Member(160L, "B");

        em.persist(member1);
        em.persist(member2);

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

        tx.commit();
        em.close();
        emf.close();
    }
}

 

예상했던것과 동일하게 insert query문이 === 으로 구분된 선 이후에 2번의 query가 날아가는 것을 확인할 수 있다.

(commit 시점에 query를 날리는 것을 확인할 수 있다.)

위에서 말했지만 해당 현상은 쓰기 지연 SQL 저장소에 query문을 저장해 놓고 commit 시점에 날리기 때문이다.