[스프링 부트] 영속성 컨텍스트

두두·2023년 2월 3일
0
post-thumbnail

[스프링부트와 aws로 혼자 구현하는 웹서비스]
를 공부하며 Chapter3에서 "영속성 컨텍스트" 라는 개념을 배워
보다 자세히 정리하고자 한다!🥰

엔티티 매니저 팩토리 & 엔티티 매니저

엔티티 매니저 팩토리

생성되는 시점에 DB 커넥션 풀을 생성해 둔 후, 고객의 요청이 들어올 때마다 엔티티 매니저를 생성

엔티티 매니저

특정 작업을 위해 데이터베이스에 액세스하는 역할을 담당
엔티티를 DB 에 등록/수정/삭제/조회(CRUD)를 담당, 엔티티와 관련된 일을 처리하는 엔티티 관리자
DB 연결이 필요한 시점(보통 트랜잭션이 시작되는 경우)에 커넥션 풀에 있는 connection을 얻음

📌 왜 엔티티 매니저 팩토리가 엔티티 매니저를 사용하는가

  • 엔티티 매니저 팩토리는 생성되는 시점에 DB 커넥션 풀을 생성하기에 생성 비용이 매우 큼.
    반면, 엔티티 매니저의 생성 비용은 거의 들지 않으므로, 엔티티 매니저 팩토리는 필요에 따라 앤티티 매니저를 생성하여 사용함
  • 엔티티 매니저 팩토리는 스레드 세이프(Thread Safe)함
    즉 여러 스레드가 동시에 접근하여도 안전한 반면, 엔티티 매니저는 여러 스레드가 동시에 접근할 경우 동시성 문제가 발생하게 됨
    ➡️ 즉, 엔티티 매니저는 절대로 공유해서는 안됨


영속성 컨텍스트란?

  • Entity를 영구 저장하는 환경
  • 애플리케이션과 데이터베이스 사이에서 객체를 보관하는 가상의 데이터베이스 같은 역할 (논리적 개념)
    엔티티 매니저를 통해 엔티티를 저장하거나 조회하면 엔티티 매니저는 영속성 컨텍스트에 엔티티를 보관하고 관리한다.
    ➡️ EntityManager가 생성되면 PersistenceContext가 1:1로 생성된다.

영속성 컨텍스트와 식별자 값

엔티티를 식별자 값(@id로 테이블의 기본 키와 매핑한 값)으로 구분한다.
따라서 영속 상태는 식별자 값이 반드시 있어야 함! 없으면 예외발생.

엔티티의 생명주기

비영속 (new/transient)

엔티티 객체를 생성했지만 아직 영속성 컨텍스트에 저장하지 않은 상태

Member member = new Member();

영속 (managed)

엔티티 매니저를 통해서 엔티티를 영속성 컨텍스트에 저장한 상태
영속성 컨텍스트에 의해 관리된다는 의미

em.persist(member);

준영속 (detached)

영속성 컨텍스트에 저장되었다가 분리된 상태
영속성 컨텍스트가 관리하던 영속 상태의 엔티티 더이상 관리하지 않으면 준영속 상태가 된다.
특정 엔티티를 준영속 상태로 만드려면 em.datach()를 호출하면 됨~

// 엔티티를 영속성 컨텍스트에서 분리해 준영속 상태로 만든다.
em.detach(member);

// 비우거나 종료해도 관리되던 엔티티는 준영속 상태가 된다.
em.claer();
em.close();

삭제 (removed)

엔티티를 영속성 컨텍스트와 데이터베이스에서 삭제함

em.persist(member);

영속성 컨텍스트가 엔티티를 관리하면 얻게되는 장점

  • 1차 캐시

  • 동일성 보장

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

  • 변경 감지

  • 지연로딩



엔티티 수정

  • JPA는 엔티티를 수정할 때는 단순히 엔티티를 조회해서 데이터만 변경하면 됨
  • update() 메소드 X
  • 변경 감지 기능을 사용해 데이터베이스에 자동 반영

수정 순서

  1. 트랜잭션 커밋 -> 엔티티 매니저 내부에서 먼저 플러시 호출
  2. 엔티티와 스냅샷을 비교해서 변경된 엔티티 찾음
  3. 변경된 엔티티가 있으면 수정 쿼리를 생성해서 쓰기 지연 SQL 저장소로 보냄
  4. 쓰기 지연 저장소의 SQL을 데이터베이스로 보냄
  5. 데이터베이스 트랜잭션을 커밋



Reference

1. 엔티티 (Entity) 와 엔티티 매니저 (Entity Manager)
JPA 영속성 컨텍스트란?
[JPA] 영속성 컨텍스트란?

profile
멋쟁이가 될테야

0개의 댓글