영속성 컨텍스트란?
JPA에서 영속성 컨텍스트는 엔티티 객체를 영속 상태(Persistent State)로 유지하고, 데이터베이스와 동기화를 담당한다. 이를 통해 데이터베이스 작업을 효율적으로 처리하고, 개발자가 직접 SQL을 작성하지 않아도 된다.
영속성 컨텍스트의 주요 역할
- 엔티티 관리: 엔티티의 생명주기를 관리한다. (비영속, 영속, 준영속, 삭제)
- 변경 감지: 엔티티 객체의 상태 변경을 감지하고, 필요한 경우 데이터베이스에 자동으로 반영한다.
- 캐싱: 동일한 엔티티를 여러 번 조회해도 동일한 인스턴스를 반환하여, 성능을 최적화한다.
- 트랜잭션과의 연계: 트랜잭션 범위 내에서만 유효하며, 트랜잭션 종료 시 데이터를 플러시(Flush)하여 데이터베이스와 동기화한다.
영속성 컨텍스트의 동작 원리
JPA는 EntityManager를 통해 영속성 컨텍스트를 제어한다. 영속성 컨텍스트의 동작은 다음과 같은 단계를 통해 이루어진다.
- 비영속 상태(Transient State)
- 새로 생성된 객체로, 아직 영속성 컨텍스트에 포함되지 않은 상태다. 즉, 영속성 컨텍스트와 전혀 관계가 없는 상태이다.
User user = new User(); user.setName("John"); // 아직 영속성 컨텍스트에 포함되지 않음
- 영속 상태(Persistent State)
- 영속성 컨텍스트에 저장되어 관리되는 상태다.
- EntityManager.persist()를 호출하거나, 데이터베이스에서 조회된 객체는 영속 상태(1차 캐시)가 된다.
- 트랜잭션의 커밋 시점에 영속성 컨텍스트에 있는 정보들이 DB에 쿼리로 날아간다.
em.persist(user); // 영속성 컨텍스트에 user가 포함됨
- 준영속 상태(Detached State)
- 영속성 컨텍스트에서 저장되었다가 분리된 상태로, 더 이상 JPA가 관리하지 않는다.
- 예: EntityManager.clear()나 EntityManager.detach()를 호출한 경우.
em.detach(user); // user는 더 이상 영속성 컨텍스트에서 관리되지 않음
- 삭제 상태(Removed State)
- 엔티티가 삭제 요청된 상태다. 데이터베이스에서 해당 데이터는 실제로 삭제된다.
em.remove(user); // user는 데이터베이스에서 삭제됨
영속성 컨텍스트의 주요 특징
- 1차 캐시 (First-Level Cache)
- 영속성 컨텍스트는 동일한 트랜잭션 내에서 엔티티를 1차 캐시에 저장한다.
- 만약, 1차 캐시에 찾는 데이터가 없다면 DB에서 해당 데이터를 가져와 1차 캐시에 저장한 후, 1차 캐시에서 해당 데이터를 반환한다.
- 동일한 엔티티를 반복 조회해도 항상 같은 객체를 반환한다.
- 1차 캐시는 전역적이지 않으며 해당되는 스레드 한개에 매핑된다. 즉, 1차 캐시는 공유되지 않는 캐시이다.
User user1 = em.find(User.class, 1L); User user2 = em.find(User.class, 1L); System.out.println(user1 == user2); // true
- 영속성 컨텍스트는 동일한 트랜잭션 내에서 엔티티를 1차 캐시에 저장한다.
- 변경 감지 (Dirty Checking)
- 엔티티의 필드 값이 변경되면 트랜잭션 커밋 시점에 자동으로 UPDATE 쿼리를 실행한다.
User user = em.find(User.class, 1L); user.setName("Updated Name"); // 변경 감지 em.flush(); // 데이터베이스에 변경 사항 반영
자세한 내용은 https://codingdoit.tistory.com/24 에서 확인할 수 있다. - 지연 로딩 (Lazy Loading)
- 엔티티의 연관 관계를 필요한 시점까지 로딩하지 않고, 실제 사용 시점에 데이터를 가져온다. 자세한 내용은 https://codingdoit.tistory.com/25 에서 확인할 수 있다.
- 동일성 보장
- 영속성 컨텍스트는 동일한 엔티티를 여러 번 조회할 때 항상 동일한 객체를 반환한다.
영속성 컨텍스트의 장점
- 성능 최적화
- 데이터베이스와의 불필요한 통신을 줄이고, 캐시를 통해 성능을 향상시킨다.
- 코드 단순화
- JPA가 상태 변화를 자동으로 감지하고 반영하므로, 개발자가 직접 SQL을 작성할 필요가 없다.
- 동일성 보장
- 동일한 엔티티를 여러 번 조회해도 같은 객체를 반환하여, 데이터 정합성을 유지한다.
영속성 컨텍스트 사용 시 주의할 점
- 메모리 관리
- 영속성 컨텍스트는 메모리를 사용하므로, 너무 많은 엔티티를 한 번에 관리하면 메모리 문제가 발생할 수 있다.
- EntityManager.clear()를 통해 주기적으로 컨텍스트를 비울 수 있다.
- 변경 감지 오버헤드
- 변경 감지 기능은 모든 엔티티를 검사하므로, 너무 많은 엔티티를 관리하면 성능 저하가 발생할 수 있다.
영속성 컨텍스트와 트랜잭션
영속성 컨텍스트는 트랜잭션 범위 내에서 동작한다. 트랜잭션이 종료되면 영속성 컨텍스트의 변경 사항이 데이터베이스에 반영되고, 이후 영속성 컨텍스트는 더 이상 유효하지 않다.
EntityTransaction tx = em.getTransaction(); tx.begin(); // 트랜잭션 시작
User user = em.find(User.class, 1L);
user.setName("New Name");
tx.commit(); // 변경 사항이 데이터베이스에 반영됨
'IT > JPA' 카테고리의 다른 글
[JPA] - 지연 로딩(Lazy Loading)과 즉시 로딩(Eager Loading) (0) | 2024.12.12 |
---|---|
[JPA] - 더티 체킹 (Dirty Checking) (0) | 2024.12.12 |