본문 바로가기
프레임워크/JPA

[JPA] 영속성 컨텍스트 (엔티티 매니저)

by Yikanghee 2022. 3. 23.

영속성 컨텍스트

  • 엔티티 메니저 팩토리와 엔티티 매니저
    • JPA는 매 요청마다 EntitityManagerFactory에서 EntityManager를 생성한다
    • EntityManager는 내부적으로 DB 커넥션 풀을 사용하해서 DB에 전달된다
    • 요청 → EntityManager Factory → EntityManager → 커넥션풀 →> DB
  • 영속성 컨텍스트란 ?
    • 영속성 컨텍스트는 “엔티티를 영구 저장하는 환경” 이라는 뜻이다
    • 영구 저장할때 그것을 영속화라고 정의하며 사용법은 EntityManager.persist(entity) 같은 형식을 사용하면 된다
    • 영속성 컨텍스트는 논리적인 개념이다
    • 아직 DB에 전달되지 않으며 DB에 전달되기 전 준비 동작이라고 이해하면 된다
  • 엔티티의 생명주기

  • 4가지의 상태가 존재한다
    • 비영속 → 전혀 관계가 없는 상태 (객체를 생성만 한 상태)
    • 영속 → 객체를 생성해서 영속화한 상태이다 트랜잭션을 사용하여 DB에 쿼리를 날릴 수 있다
    • 준영속 → 영속성 컨텍스트에 저장되었다가 분리된 상태
    • 삭제 → 삭제된 상태, DB에서도 삭제시킨다
  • 영속성 컨텍스트를 사용하는 이유
    • 1차 캐시
      • 영속성 컨텍스트 (entityManager) 에는 내부 1차 캐시가 존재한다
      • 엔티티를 영속성 컨텍스트에 저장하는 순간 1차캐시에 보내지고 key, value 상태로 관리된다
      • 1차 캐시를 사용하는 가장 큰 이유는 조회할때 효율적이다
      • 조회할때 DB에 들리지 않고 1차 캐시에 엔티티가 존재하면 바로 반환한다
      • 그렇다면 1차 캐시가 없다면? 데이터 베이스에서 조회한다
    • 동일성 보장
      • 영속 엔티티의 동일성을 보장한다
      Member member1 = em.find(Member.class, "Member1");
      Member member2 = em.find(Member.class, "Member2");
      
      System.out.println( a == b ); //true
      
  • 트랜잭션 / 지연 쓰기
    • 트랜잭션 내부에서 persis()가 발생할때 엔티티들을 1차 캐시에 저장하고, 논리적으로 쓰기 지연 SQL 저장소라는 곳에 INSERT 쿼리들을 생성해서 쌓아 놓는다
    • 그리고 DB에 바로 넣지 않고 기다리다가 트랜잭션 COMMIT 하는 시점에 DB에 쿼리들을 한번에 보낸다
    • 이렇게 쌓여있는 쿼리들을 DB에 보내는 동작을 flush()라고 한다
    • flush()는 1차 캐시를 지우지 않고 쿼리들을 DB에 날려서 DB와 싱크를 맞추는 역할을 수행한다
    EntityManager em = emf.createEntityManager();
    EntityTransaction transaction = em.getTransaction();
    // 엔티티 매니저는 데이터 변경시 트랜잭션을 시작해야 한다.
    transaction.begin(); // 트랜잭션 시작
    
    em.persist(memberA);
    em.persist(memberB);
    // 이때까지 INSERT SQL을 데이터베이스에 보내지 않는다.
    
    // 커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다.
    transaction.commit(); // 트랜잭션 커밋
    
    • 트랜잭션의 크기는 persisten.xml에서 설정할 수 있다
      • JDBC 일괄 처리 옵션으로 커밋 직전까지 insert 쿼리를 해당 사이즈 만큼 모아서 한번에 처리한다
<property name="hibernate.jdbc.batch_size" value=10/>

댓글