[JPA] 영속성 컨텍스트 특징 쓰기지연과 변경감지의 장점

    DB에서 데이터를 조회하는 것은 애플리케이션 서버 안에서 실행되는 메서드 보다 비교도 안될 정도로 시간 비용이 많이 든다. 그래서 DB에서 데이터를 조회하는 것을 최소화하는 것이 성능 최적화의 중요 요점이라고 볼 수 있다.

     

    JPA 동작원리

    애플리케이션 내에서 EntityManager는 EntityManagerFactory 객체에서 만들어지는데 EntityManagerFactory객체는 한개만 있고  EntityManager는 여러개 만들어 낸다. EntityManager는 한개의 트랜잭션을 가질 수 있다. EntityManager가 관리하는 트랜잭션 내에서 애플리케이션 성능을 높이기 위해 영속성 컨텍스트라는 개념이 나온다.

     

    영속성 컨텍스트란

    JPA 내부 동작 방식을 이해하려면 영속성 컨텍스트를 이해해야 하는데 영속성 컨텍스트는 엔티티 매니저를 통해서 만들어진 DB의 로우 단위 객체인 엔티티를 영구 저장하는 장소이다. 이 영속성 컨텍스트의 특징 중에 1차 캐시라는 것이 있는데 이것은 영속성 컨텍스트가 가지고 있는 Map 구조의 데이터라고 보면 된다. 이 Map의 키는 @Id, 값은 엔티티 인스턴스이다. 

     

     memberA, memberB의 객체를 영속성 컨텍스트에 저장 하면 아래와 같이 하면 된다.

    EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
    EntityManager em = emf.createEntityManager();
    EntityTransaction tx = em.getTransaction();
    
    tx.begin();
    
    Member memberA = new Member();
    Member memberB = new Member();
    em.persist(memberA);
    em.persist(memberB);
    
    tx.commit();

     

    회원 Entity인 Member 클래스의 객체를 persist 하면 영속성 컨텍스트 안에 들어가게 되는데 이는 위 그림과 같이 Map 구조로 되어있는 1차 캐시로 들어가게 된다. 

     

    영속성 컨텍스트 생명주기

    영속성 컨텍스트는 4가지 생명주기가 존재하는데 비영속(new/transient), 영속(managed), 준영속(detached), 삭제(removed)가 있다.  비영속은 말 그대로 영속되지 않은 상태로 영속성 컨텍스트와 관계가 없는 상태이며, 즉 persist() 하지 않은 상태이다. 영속은 영속성 컨텍스트에 저장된 상태, 준영속은 영속성 컨텍스트에 저장되었다가 분리된 상태, 삭제는 영속성 컨텍스트가 삭제된 상태이다.

     

    쓰기지연 특징과 장점

    영속성 컨텍스트의 여러가지 특징중 하나의 큰 특징이 있는데 persist() 함수를 통해서 영속 상태에 들어간 상태는 아직 DB에 쿼리가 실행되기 전이다. 실행할 쿼리들은 쓰기지연 SQL 저장소에 저장되고 flush() 함수를 통해서 저장된 쿼리들이 한번에 실행된다. 이는 쿼리들을 한번에 실행시켜 DB 연결하는 횟수를 최소한으로 하여 성능 향상에 큰 도움이 된다. 이것이 쓰기 지연 특징이다.

    참고 : flush() 함수는 트랜잭션 commit 할때 자동으로 실행된다.

     

    그래서 영속 상태인것은 엔티티 매니저를 통해서 엔티티를 영속성 컨텍스트에 저장했다는 것이고 find() 함수를 통해 한개의 트랜잭션에 속한 (1차 캐시안에 있는 데이터) 데이터들을 공유할 수 있다.  이것이 1차 캐시의 특징이다.

     

    변경 감지 특징과 중요 이유

    엔티티 업데이트는 하는 방법은 set 함수를 통해 필드만 변경해줘도 update 쿼리문이 실행 돼서 업데이트가 된다.

    memberA.setName("hi");

     

    엔티티의 변경사항을 데이터베이스에 자동으로 반영되게 하는 기능을 변경 감지(dirty checking) 이라고 한다. 영속성 컨텍스트에 들어갈때 처음 memberA 인스턴스에 대한 데이터를 저장하고 memberA의 데이터를 변경하면 또 1차 캐시안에 들어가게 되는데 트랜잭션 commit 시점에 데이터의 비교를 감지하고 쿼리를 만들어서 실행되게 하는 것이다. 이 과정은 개발자가 수동으로 데이터를 업데이트를 하는 번거로움을 줄여줌과 동시에 변경한 데이터와 DB의 데이터의 일관성을 자동으로 유지할 수 있게 해준다.

    만약에 이게 싫으면 detach(memberA) 하여 엔티티를 준영속 상태로 만들면 된다.

    준영속 상태로 만들면 변경 감지를 하지 않는다.

     

     

     

    참고 : 김영한 / 자바 ORM 표준 프로그래밍

     

     

     

     

     

     

    'Language > JPA' 카테고리의 다른 글

    [JPA] 테이블 Entity 매핑과 필드 매핑 유의사항  (1) 2024.03.06

    댓글

    Designed by JB FACTORY