Back-end/SpringBoot

Persistence Context란 무엇일까?

xeunnie 2024. 7. 15. 04:40
728x90
반응형

영속성 컨텍스트(Persistence Context)란?

JPA(Java Persistence API)의 핵심 개념 중 하나로, 엔티티 객체를 관리와 데이터베이스와의 동기화를 담당하고 한다.

  • Entity의 생명 주기를 관리

  • 데이터베이스와의 상호 작용을 효율적으로 처리하는 역할

  • 객체 지향적인 방법으로 데이터베이스 작업 가능

  • 성능 최적화 및 데이터 일관성을 보장

  • 특정 엔티티 매니저(EntityManager)와 관련된 저장소 -> 엔티티 매니저를 통해 관리되는 엔티티 객체들을 보관

결론

영속성 컨텍스트는 JPA의 강력한 기능으로, 이를 통해 개발자는 객체 지향적인 방식으로 데이터베이스 작업을 수행할 수 있으며, 니다. 하지만 메모리 관리와 준영속 상태의 엔티티 처리에 주의를 기울여야 합니다.

주로 하는 일

  1. 엔티티의 생명 주기 관리:

    • 비영속 상태(Transient):
      데이터베이스와 전혀 관련이 없는 상태로, 단순히 메모리에만 존재하는 객체,
      new를 통해 생성된 객체가 비영속 상태에 해당한다!
    • 영속 상태(Persistent):
      영속성 컨텍스트에 의해 관리되는 상태로, 데이터베이스와 동기화될 수 있는 상태,
      EntityManager.persist() 메서드를 통해 비영속 상태의 객체를 영속 상태로 전환할 수 있다.
    • 준영속 상태(Detached):
      한때 영속 상태였지만 현재는 영속성 컨텍스트에 의해 더 이상 관리되지 않는 상태,
      EntityManager.detach(), EntityManager.clear(), EntityManager.close()
      메서드를 호출하거나 트랜잭션이 끝날 때 발생할 수 있다.
    • 삭제 상태(Removed):
      영속성 컨텍스트에 의해 관리되지만 삭제되기로 마킹된 상태,
      EntityManager.remove() 메서드를 통해 전환할 수 있다.
  2. 1차 캐시:

    • 엔티티 객체를 1차 캐시라고 불리는 메모리에 저장
      이를 통해 동일한 트랜잭션 내에서 동일한 엔티티에 대한 여러 번의 데이터베이스 접근을 피할 수 있다.
      즉, 동일한 엔티티에 대해 반복적으로 find 또는 getReference 메서드를 호출해도 동일한 인스턴스를 반환한다.
  3. 동일성 보장:

    • 동일한 영속성 컨텍스트 내에서는 동일한 엔티티에 대해 동일한 인스턴스를 보장
      엔티티의 식별자가 같다면 같은 인스턴스가 반환된다. -> 애플리케이션의 데이터 일관성을 유지하는 데에 중요
  4. 변경 감지(Dirty Checking):

    • 트랜잭션이 끝날 때 엔티티의 변경 사항을 감지, 데이터베이스에 자동으로 반영
      개발자가 명시적으로 updatesave 메서드를 호출하지 않아도 엔티티의 상태가 데이터베이스에 동기화된다.
  5. 지연 로딩(Lazy Loading):

    • 엔티티 관계에서 지연 로딩을 설정시, 관련된 엔티티를 실제로 사용할 때까지 데이터베이스 조회를 지연 가능
      지연 로딩은 성능 최적화에 도움이 되는데, 영속성 컨텍스트가 이를 관리한다.

활용 예제

@Entity
public class Member {
    @Id @GeneratedValue
    private Long id;
    private String name;

    // getters and setters
}

public class JpaExample {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("example-unit");
        EntityManager em = emf.createEntityManager();

        em.getTransaction().begin();

        // 비영속 상태
        Member member = new Member();
        member.setName("John");

        // 영속 상태
        em.persist(member);

        // 1차 캐시에서 조회
        Member findMember = em.find(Member.class, member.getId());

        // 변경 감지
        findMember.setName("Doe");

        em.getTransaction().commit();
        em.close();
        emf.close();
    }
}

장점

  1. 성능 최적화:
    1차 캐시와 지연 로딩 -> 데이터베이스 접근 횟수 감소, 성능을 최적화 가능

  2. 데이터 일관성 보장:
    동일한 영속성 컨텍스트 내에서는 동일한 엔티티에 대해 동일한 인스턴스를 보장 -> 데이터 일관성을 유지

  3. 트랜잭션 관리:
    트랜잭션이 끝날 때 자동으로 변경 사항을 데이터베이스에 반영 -> 코드의 간결성을 높아짐

주의사항

  1. 메모리 관리:
    1차 캐시에 많은 엔티티가 쌓이면 메모리 사용량이 증가할 수 있다.
    적절한 시점에 cleardetach 메서드를 사용해 메모리를 관리해야 한다.

  2. 준영속 상태의 엔티티:
    준영속 상태의 엔티티를 다시 영속 상태로 전환하려면 merge 메서드를 사용 -> 이때 과정에서 새로운 인스턴스가 반환! (주의 필요)

728x90
반응형