Spring/Spring JPA / / 2024. 3. 14. 15:30

JPA 영속성 컨텍스트

영속성 컨텍스트

영속성 컨텍스트(Persistence Context)는 JPA에서 엔티티를 영구 저장하는 환경을 말합니다. 이는 엔티티 매니저(Entity Manager)에 의해 관리되며, 엔티티의 생명주기를 관리하고, 엔티티의 인스턴스 상태를 관리하고, 데이터베이스와의 동기화를 담당합니다.

영속성 컨텍스트는 1차 캐시와 엔티티의 상태 및 생명주기 관리, 더티 체킹, 쓰기지연과 같은 다양한 기능을 바탕으로 애플리케이션과 데이터베이스 사이에서 엔티티의 일관성을 유지하고, 성능을 최적화하는 데 중요한 역할을 합니다.

 

엔티티의 생명주기

  • 비영속 (New/Transient): 엔티티가 새로 생성되었지만 아직 영속성 컨텍스트에 포함되지 않은 상태입니다. 이 시점에서는 데이터베이스에 저장되지 않습니다.
  • 영속 (Managed): 엔티티가 영속성 컨텍스트에 포함되어 관리되는 상태입니다. 이 상태의 엔티티는 데이터베이스에 저장되거나, 저장될 예정입니다.
  • 준영속 (Detached): 영속 상태였던 엔티티가 영속성 컨텍스트로부터 분리된 상태입니다. 이 상태의 엔티티는 더 이상 영속성 컨텍스트에 의해 관리되지 않습니다.
  • 삭제 (Removed): 엔티티가 삭제되어야 하는 상태입니다. 이 상태의 엔티티는 트랜잭션이 커밋되는 시점에 데이터베이스에서도 삭제됩니다.

1차 캐시 (First Level Cache)

1차 캐시는 트랜잭션 범위 내에서 엔티티를 캐싱하는 메커니즘으로, 엔티티 매니저의 생명주기 동안 유지됩니다. JPA는 데이터베이스에서 엔티티를 조회할 때, 먼저 1차 캐시에서 해당 엔티티를 찾고, 없을 경우 데이터베이스에서 로드하여 1차 캐시에 저장합니다. 이후 같은 트랜잭션 내에서 동일한 엔티티에 대한 조회 요청이 있을 경우, 1차 캐시에서 바로 엔티티를 반환합니다. 이는 데이터베이스 접근 횟수를 줄이고, 성능을 향상시키는 데 도움을 줍니다.

쓰기 지연 (Write Behind)

쓰기 지연은 JPA가 트랜잭션을 효율적으로 관리하기 위해 사용하는 전략 중 하나입니다. JPA는 엔티티에 대한 변경사항(삽입, 수정, 삭제)을 즉시 데이터베이스에 반영하지 않고, 컨텍스트 내의 쓰기 지연 SQL 저장소에 모읍니다. 트랜잭션이 커밋되는 시점에 모아둔 SQL을 데이터베이스에 전송합니다. 이 방식은 네트워크 사용을 줄이고, 데이터베이스와의 상호작용을 최적화하여 성능을 향상시킵니다.

더티 체킹 (Dirty Checking)

더티 체킹은 JPA가 Managed 상태의 엔티티에 대한 변경사항을 자동으로 감지하고 데이터베이스에 반영하는 기능입니다. 개발자는 엔티티 객체의 필드 값을 변경하기만 하면, JPA는 트랜잭션이 커밋될 때 변경사항을 데이터베이스에 자동으로 반영합니다. 이는 명시적인 저장 메서드 호출 없이 데이터의 일관성을 유지할 수 있게 해줍니다.

 

예제

@Repository
public class ExampleRepository {

    @PersistenceContext
    private EntityManager entityManager;

    @Transactional
    public void exampleOperation() {
        // 비영속 상태의 엔티티 생성
        ExampleEntity newEntity = new ExampleEntity();
        newEntity.setName("New Entity");

        // 엔티티를 영속 상태로 만듦 (1차 캐시에 저장됨)
        entityManager.persist(newEntity);

        // 쓰기 지연: SQL 저장소에 INSERT SQL이 저장됨. 실제 DB 반영은 트랜잭션 커밋 시점에 이루어짐
        // 이 시점에서는 아직 데이터베이스에 반영되지 않았음

        // 1차 캐시에서 조회 (데이터베이스 접근 없음)
        ExampleEntity cachedEntity = entityManager.find(ExampleEntity.class, newEntity.getId());

        // 더티 체킹: 엔티티의 상태 변경 감지
        cachedEntity.setName("Updated Entity");

        // 트랜잭션 커밋 시점에 변경 감지된 엔티티의 업데이트 SQL이 실행됨 (더티 체킹에 의한 자동 업데이트)
        // 변경된 엔티티는 데이터베이스에 반영됨

        // 엔티티 삭제
        entityManager.remove(cachedEntity);

        // 삭제된 엔티티는 트랜잭션 커밋 시 데이터베이스에서 삭제됨 (Removed 상태)
    }
}

 

'Spring > Spring JPA' 카테고리의 다른 글

JPA란?  (0) 2024.03.13
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유