영속성 컨텍스트(Persistence Context)란?
JPA(Java Persistence API)의 핵심 개념 중 하나로, 엔티티 객체를 관리와 데이터베이스와의 동기화를 담당하고 한다.
Entity의 생명 주기를 관리
데이터베이스와의 상호 작용을 효율적으로 처리하는 역할
객체 지향적인 방법으로 데이터베이스 작업 가능
성능 최적화 및 데이터 일관성을 보장
특정 엔티티 매니저(EntityManager)와 관련된 저장소 -> 엔티티 매니저를 통해 관리되는 엔티티 객체들을 보관
결론
영속성 컨텍스트는 JPA의 강력한 기능으로, 이를 통해 개발자는 객체 지향적인 방식으로 데이터베이스 작업을 수행할 수 있으며, 니다. 하지만 메모리 관리와 준영속 상태의 엔티티 처리에 주의를 기울여야 합니다.
주로 하는 일
엔티티의 생명 주기 관리:
- 비영속 상태(Transient):
데이터베이스와 전혀 관련이 없는 상태로, 단순히 메모리에만 존재하는 객체,
new
를 통해 생성된 객체가 비영속 상태에 해당한다! - 영속 상태(Persistent):
영속성 컨텍스트에 의해 관리되는 상태로, 데이터베이스와 동기화될 수 있는 상태,
EntityManager.persist()
메서드를 통해 비영속 상태의 객체를 영속 상태로 전환할 수 있다. - 준영속 상태(Detached):
한때 영속 상태였지만 현재는 영속성 컨텍스트에 의해 더 이상 관리되지 않는 상태,
EntityManager.detach()
,EntityManager.clear()
,EntityManager.close()
메서드를 호출하거나 트랜잭션이 끝날 때 발생할 수 있다. - 삭제 상태(Removed):
영속성 컨텍스트에 의해 관리되지만 삭제되기로 마킹된 상태,
EntityManager.remove()
메서드를 통해 전환할 수 있다.
- 비영속 상태(Transient):
1차 캐시:
- 엔티티 객체를 1차 캐시라고 불리는 메모리에 저장
이를 통해 동일한 트랜잭션 내에서 동일한 엔티티에 대한 여러 번의 데이터베이스 접근을 피할 수 있다.
즉, 동일한 엔티티에 대해 반복적으로find
또는getReference
메서드를 호출해도 동일한 인스턴스를 반환한다.
- 엔티티 객체를 1차 캐시라고 불리는 메모리에 저장
동일성 보장:
- 동일한 영속성 컨텍스트 내에서는 동일한 엔티티에 대해 동일한 인스턴스를 보장
엔티티의 식별자가 같다면 같은 인스턴스가 반환된다. -> 애플리케이션의 데이터 일관성을 유지하는 데에 중요
- 동일한 영속성 컨텍스트 내에서는 동일한 엔티티에 대해 동일한 인스턴스를 보장
변경 감지(Dirty Checking):
- 트랜잭션이 끝날 때 엔티티의 변경 사항을 감지, 데이터베이스에 자동으로 반영
개발자가 명시적으로update
나save
메서드를 호출하지 않아도 엔티티의 상태가 데이터베이스에 동기화된다.
- 트랜잭션이 끝날 때 엔티티의 변경 사항을 감지, 데이터베이스에 자동으로 반영
지연 로딩(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차 캐시에 많은 엔티티가 쌓이면 메모리 사용량이 증가할 수 있다.
적절한 시점에clear
나detach
메서드를 사용해 메모리를 관리해야 한다.준영속 상태의 엔티티:
준영속 상태의 엔티티를 다시 영속 상태로 전환하려면merge
메서드를 사용 -> 이때 과정에서 새로운 인스턴스가 반환! (주의 필요)
'Back-end > SpringBoot' 카테고리의 다른 글
AWS S3 사용하는법! (2) | 2024.07.15 |
---|---|
스프링에서 DB 트랜잭션을 어떻게 사용할까? (0) | 2024.07.15 |
JWT 토큰 기반 로그인 구현하기(1) (0) | 2024.07.08 |
Bean이란 무엇일까? (0) | 2024.06.24 |
의존성 주입이란 무엇일까? (0) | 2024.06.23 |