본문 바로가기

Spring Boot

[Spring Boot] 영속성 컨텍스트(Persistence Context)

영속성 컨텍스트란?

JPA 에서 엔티티(Entity)를 저장하고 관리하는 메모리 상의 저장소이며

일반적으로 EntityManager가 생성될 때 함께 생성되고 EntityManager가 종료되면 함께 사라집니다.

 

EntityManager란?

JPA의 핵심 객체로 DB와의 모든 상호작용을 담당하는 객체로써 영속성 컨텍스트도 EntityManager 내부에 존재하며 CRUD 등의 작업은 모두 EntityManager를 통해 이루어집니다.

 

 

영속성 컨텍스트 상태에 따른 엔티티 생명 주기

비영속성(Transient) : 아직 영속성 컨텍스트에 저장되지 않은 상태(new로 만든 객체 등)

영속(Persistent) : 영속성 컨텍스트에 저장된 상태(em.persist() 호출 등)

준영속(Detached) : 영속성 컨텍스트에서 분리된 상태(em.detach(), close() 등)

삭제(Removed): em.remove()가 호출되어 영속성 컨텍스트에서는 삭제 대상으로 표시된 상태. 아직 DB에서는 삭제되지 않았고, 트랜잭션 커밋 시 삭제 쿼리가 실행됩니다.

 

 

영속성 컨텍스트 주요 특징

1. 1차 캐시(First-Level Cache)

2. 동일성 보장

3. 트랜잭션을 지원하는 지연 쓰기

4. 변경 감지

5. 지연 로딩

 

 

 

1차 캐시

영속성 컨텍스트 내부에 캐시가 존재하며 이를 1차캐시라고 하며 영속 상태의 앤티티를 1차캐시에 저장을 하여 빠르게 조회가 가능합니다. 식별자 값은 기본키(PK)를 이용하여 찾고 값은 앤티티의 인스턴스입니다.

 

조회의 흐름
1. 1차 캐시에서 엔티티를 찾는다
2. 있으면 메모리에 있는 1차 캐시에서 엔티티를 조회한다.
3. 없으면 데이터베이스에서 조회한다.
4. 조회한 데이터로 엔티티를 생성해 1차 캐시에 저장한다.
5. 조회한 엔티티를 반환한다.

 

 

변경 감지

JPA로 엔티티를 수정할 때는 단순히 엔티티를 조회해서 데이터를 변경하면 된다.

변경감지의 흐름
1. 트랙잭션을 커밋하면 엔티티 매니저 내부에서 먼저 플러시가 호출된다.
2. 엔티티와 스냅샷을 비교하여 변경된 엔티티를 찾는다.
3. 변경된 엔티티가 있으면 수정 쿼리를 생성해서 쓰기 지연 SQL 저장소에 저장한다.
4. 쓰기 지연 저장소의 SQL을 플러시한다.
5. 데이터베이스 트랜잭션을 커밋한다.

변경 감지는 영속성 컨텍스트가 관리하는 영속 상태의 엔티티만 적용된다.

 

※ 플러시

플러시는 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영합니다. 영속성 컨텍스트의 엔티티를 지우는게 아니라 변경 내용을 데이터베이스에 동기화하는 작업을 말합니다.

 

플러시의 흐름
1. 변경 감지가 동작해서 스냅샷과 비교해서 수정된 엔티티를 찾는다.
2. 수정된 엔티티에 대해서 수정 쿼리를 만들거 SQL 저장소에 등록한다.
3. 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송한다.

 

플러시하는 방법
1. em.flush()
2. 트랙잭션 커밋시 자동 호출
3. JPQL 쿼리 실행시 자동 호출

 

 

지연 로딩

OneToMany, ManyToOne 관계로 이루어진 객체 중 하나를 조회 했을 때 해당 관계와 연관되어 있는 모든 객체들이 DB에서 호출되게 됩니다. 만약 UserEntity 1 : N PostEntity 관계로 이루어져있을 때 UserEntity의 정보만 사용할려고 객체를 조회해서 가지고 왔을 때 자동으로 List<PostEntity> 까지 가지고 오게 되는 것입니다. 영속성 컨텍스트 지연로딩은 UserEntity를 조회했을 때 관계가 이루어진 객체를 사용하기 전까지 프록시 객체로 가지고 있다가 만약 해당 관계가 이어진 객체들에게 접근 했을 때 DB 에 접근하여 가져오게 됩니다.

 

지연 쓰기

DB에 즉시 반영하지 않고 트랜잭션이 커밋되기 전까지 SQL 저장소에 모아두었다가, 커밋 시 한꺼번에 실행합니다. 이를 쓰기 지연(Write-behind) 또는 지연 쓰기라고 합니다.

 

 

 

 

'Spring Boot' 카테고리의 다른 글

[Spring Boot] QR Code 발급하기  (0) 2025.05.17
[Spring Boot] Scheduler  (0) 2025.05.01
[Spring Boot] 파일 저장 시스템  (1) 2025.04.26
[Spring Boot] Optional  (0) 2025.04.16
[Spring boot] 프록시 객체(Proxy Object)  (1) 2025.03.29