SpringBoot #4.3 영속성 컨텍스트

텐저린티·2023년 7월 25일
0

데브코스

목록 보기
34/41
post-thumbnail

Summary

  • EntityManagerFactory
  • EntityManager
  • 영속성 컨텍스트
  • 엔티티 생명주기
  • 영속성 컨텍스트 특징

Entity

  • RDB table에 매핑되는 객체
@Entity
@Table(name = "tickets")
public class Ticket {
		@Id // Id PK
		private long id;
		private long price;
		private LocalDate reservedDate;

		// getter and setter
}

EntityManagerFactory

  • Entity 관리하는 EntityManager 생성 팩토리 클래스
  • Thread Safe

EntityManager

  • Entity CRUD (저장, 수정, 삭제, 조회) 등 Entity 관련 모든 작업 처리
  • Non Thread Safe
    • 여러 Thread에서 동시 접근 시 동시성 이유 발생 가능
  • EntityManager는 Transaction 시작 시 Connection 획득

영속성 컨텍스트

개념

  • JPA 이용에 가장 중요한 핵심 요소
  • Entity 영구 저장 환경
  • EntityManager는 Entity를 영속성 컨텍스트에 보관, 관리

특징

  • 식별자
    • 영속성 컨텍스트에서 관리되는 Entity는 반드시 식별자 값 가짐.
    • key-value 로 영속성 컨텍스트가 엔티티 관리하기 때문에 식별자 필요
    • @Id
  • 데이터 베이스 저장
    • 트랜잭션 커밋 시 DB 반영
      • JPA 는 Transaction 커밋 순간에 영속성 컨텍스트에 새로 저장된 Entity를 DB에 반영 (Flush)
    • Flush
      • 영속성 컨텍스트 변경 내용을 DB에 동기화하는 작업
      • 등록, 수정, 삭제한 Entity (변경 내용) 를 DB에 반영하는 작업
  • 영속성 컨텍스트가 엔티티 관리하는 이점
    • 1차 캐시
    • 동일성 보장
    • Transaction 지원하는 쓰기 지연
    • 변경 감시 (Dirty Checking)
    • 지연 로딩

Entity LifeCycle

  • 비영속 - new (transient)
    • 영속성 컨텍스트와 전혀 관계 없는 상태
  • 영속 - managed
    • 영속성 컨텍스트에 저장된 상태
  • 준영속 - detached
    • 영속성 컨텍스트에 저장되었다가 분리된 상태
  • 삭제 - removed
    • 삭제된 상태

  • persist()
    • entity를 영속성 컨텍스트에서 관리
    • entity 를 key-value로 1차 캐시에 저장
    • 쿼리를 쓰기 지연 저장소에 저장
  • detach()
    • 영속상태 엔티티를 영속성 컨텍스트에서 분리
  • clear()
    • 영속상태 모든 엔티티를 영속성 컨텍스트에서 분리
  • close()
    • 영속성 컨텍스트 종료
  • remove()
    • 엔티티를 영속성 컨텍스트에서 분리, DB에서 삭제

예시

  • 저장
EntityManager em = emf.createEntityManager(); // 1)엔티티 매니저 생성

EntityTransaction transaction = em.getTransaction(); // 2)트랜잭션 획득
transaction.begin(); // 3)트랙잰셕 begin

Customer customer = new Customer(); // 4-1)비영속
customer.setId(1L);
customer.setFirstName("honggu");
customer.setLastName("kang");

// entity를 key-value로 1차 캐시에 저장
// 쿼리를 쓰기 지연 저장소에 저장
em.persist(customer); // 4-2)영속화

// 트랜잭션이 커밋이 되는 순간 쿼리가 수행된다. flush DB와 동기화가 된다.
// 커밋 순간 flush
// flush되면, 1차 캐시에 있던 내용, 쓰기 지연 저장소에 있던 쿼리가 실행
transaction.commit(); // 5)트랜잭션 commit

  • 조회

    • 1차 캐시 이용 조회
      • 영속성 컨텍스트 내 1차 캐시에 Entity에 대한 key-value가 있는 경우

      • DB까지 가지 않음

      • 1차 캐시에서 결과 찾아서 반환

      • SQL 실행 X

        em.persist(customer);
        transaction.commit();
        
        // 1차 캐시에서 조회
        Customer entity = em.find(Customer.class, 1L);

    • DB 이용 조회
      • 1차 캐시에 entity에 대한 key가 없는 경우

      • DB에서 결과 반환

      • SQL 실행 O

        em.persist(customer);
        transaction.commit();
        
        em.clear();
        
        // DB에서 조회 -> SQL 실행
        Customer entity = em.find(Customer.class, 2L);
        // 1차 캐시에서 조회 -> SQL 쿼리 실행 X
        em.find(Customer.class, 2L);

  • 수정

    • 스냅샷
      • JPA가 Entity를 영속성 컨텍스트에 보관할 때, 최초 상태 복사해서 저장해두는 것
    • 변경 감지 (Dirth Checking)
      • flush (commit) 시점에 스냅샷과 엔터티 비교해서 변경된 entity 찾음
      • 스냅샷과 비교해서 변경 내용 있는 경우 update query 수행
      • 변경 감지는 영속성 컨텍스트 내에서 관리되는 영속 상태 (managed) entity에만 적용
      • 비영속 객체는 변경감지 하지 않음
        em.persist(customer);
        // entity 영속화 후, 커밋(flush()) 통해 DB 저장
        transaction.commit();
        
        transaction.begin();
        
        Customer entity = em.find(Customer.class, 1L);
        entity.setName("다른이름");
        
        // entity를 update하지 않아도,
        // 더티체킹으로 entity 와 스냅샷 비교 후
        // commit 시점에 쿼리 날려줌
        transaction.commit();
  • 삭제

    em.persist(customer);
    transaction.commit();
    
    transaction.begin();
    
    Customer entity = em.find(Customer.class, 1L);
    em.remove(entity);
    
    transaction.commit(); // flush -> DELETE ..
profile
개발하고 말테야

0개의 댓글

관련 채용 정보