Java

영속성 컨텍스트(Persistence Context)

notion image

정의

Server와 Database 사이에 Entity를 저장하는 논리적인 영역

목적 및 특징

어플리케이션과 DB 사이에서 객체를 보관하는 가상의 DB같은 역할
 

영속성

데이터를 생성한 프로그램이 종료되더라도 사라지지 않는 데이터의 특성
EntityManager로 엔티티를 저장하거나 조회하면, EntityManager는 영속성 컨텍스트에 Entity를 보관하고 관리한다.
영속성 컨텍스트는 엔티티 매니저(Session)를 생성할 때 하나 만들어진다.
그리고 엔티티 매니저(Session)을 통해서 영속성 컨텍스트에 접근할 수 있고 영속성 컨텍스트를 관리할 수 있다.
  1. 1차 캐시에 저장 및 조회
    1. 영속성 컨텍스트는 내부에 엔티티를 저장하는 캐시를 가지고 있는데 이것을 1차 캐시라고 한다. 영속 상태의 엔티티는 데이터 베이스에 저장되기 전(트랜잭션 호출 전)까지 모두 이곳에 저장된다. 엔티티 조회 시 1차 캐시에서 먼저 찾고 만약 존재하지 않으면 데이터베이스를 조회한다. 이러한 기능으로 성능상에 이점을 누릴 수 있다.
    2. Map 객체로 저장 : 엔티티를 식별자 값(@Id 매핑)으로 구분한다. Key-value로 관리하는데 이때 key 값이 @Id 값이 된다. 식별자 값 필요 : 영속상태의 엔티티는 반드시 식별자 값이 있어야 한다.
  1. 트랜잭션을 지원하는 쓰기 지원
    1. JPA는 보통 트랜잭션을 커밋하는 순간 쓰기 지연 저장소에 쌓아 놨던 SQL을 데이터베이스에 Flush한다.
  1. 동일성 보장
    1. 동일한 트랜잭션에서 조회한 Entity는 같음을 보장
  1. 변경 감지(Dirty Checking)
    1. 영속성 상태의 객체는 객체의 데이터가 변경이 되면, 자동 update 된다. (EntityManager에서 flush가 되고, commit이 된다.)
    2. Flush 시점에서 엔티티와 스냅샷을 비교해 변경된 엔티티가 있다면 쓰기 지연 SQL 저장소에 보낸다. 따라서, 엔티티 수정에 대한 메서드가 필요없다.
  1. 지연 로딩(Lazy Loading)
    1. 지연 로딩: 필요한 시점에 연관된 데이터를 불러오는 것
      1. 프록시 이용
        1. 실제 엔티티 대신에 사용되는 객체로 원본 엔티티를 상속받은 객체다. 초기에 DB로부터 조회가 되면 프록시 객체의 타겟으로 실제 객체가 연결이 되면서 최초에 1회 초기화된다. 그 이후로는 지속적으로 호출해도 프록시가 초기화되지는 않고 한번 호출한 걸 계속 쓴다.
    2. 즉시 로딩: 데이터를 조회할 때 연관된 데이터까지 한 번에 불러오는 것

Flush 시점

  • 강제 Flush: EntityManager.flush()
  • 트랜잭션 종료시: 영속성 컨텍스트는 트랜잭션 범위로 만들어지기 때문이다.
  • JPQL 쿼리 실행: JPQL은 실제 Database side에서 데이터를 가져오기 때문에 동기화를 위해 JPQL 쿼리가 실행 전에 flush 된다.

면접 질문

  • 영속성 컨텍스트가 무엇인가요?
  • 영속성 컨텍스트의 특징은 무엇인가요?
  • 영속성 컨텍스트는 조회, persist 시에 데이터가 1차 캐시에 저장됩니다. 이러한 데이터들의 Flush 시점에 대해 설명해주세요.