Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |
Tags
- html #css #부트스트랩 #웹사이트 #개발 #초보 #til #내일배움캠프 #스파르타코딩클럽
- sql #내일배움캠프 #스파르타코딩클럽
- java
- java #문법
- sql #부트캠프 #내일배움캠프 #웹관리자 #도전 #학습
Archives
- Today
- Total
Hyeok의 웹 개발 블로그
<2025.05.01> 영속성 컨텍스트 본문
✅영속성이란?
- 영속성( 永(길게) 續(속하다) - Persistence)이란, 프로그램이 종료된 이후에도 데이터가 사라지지 않고 저장되는 성질을 말합니다.
- 즉, 메모리(휘발성 공간)가 아닌 디스크(비휘발성 저장소)에 데이터를 영구히 보존하겠다라는 강력한 의지가 나타내기 위한 것입니다.

✅JPA에서 영속성이란?
- JPA는 객체(Entity)와 데이터베이스 테이블(Table)간의 중간자 역할을 하며, 자바 객체를 데이터베이스에 ‘영속’시키는 과정을 관리하기 위한 라이브러리에요.
- 한명의 유치원 선생님이 여러 유치원생을 관리하려면 유치원이라는 환경이 필요하듯 여러 객체를 관리하기 위한 환경이 바로 영속성 컨텍스트(Persistence Context) 라는 메모리 영역을 필요해요.
- 그래서 JPA에서의 영속성은 영속성 컨텍스트(Persistence Context) 에 등록한 객체의 추이를 관찰하다 DB에 어떻게 영구히 저장할 것인가를 정하는 과정인 것이죠.
- JPA에서 영속은 영속성 컨텍스트에 객체를 등록된 상태.
- 영속 (managed)
- 영속성 컨텍스트에 등록된 상태
- find(),save()
- 비영속(new/transient)
- 영속성 컨텍스트에 등록되지 않은 상태
- 준영속 (detached)
- 영속성 컨텍스트에 저장되었다가 분리된 상태
- 준영속 상태의 엔티티는 컨텍스트가 제공하는 기능을 사용X
- clear() , refresh()
- 삭제(removed)
- 영속성 컨텍스트에서 제외되며 SQL 저장소에 delete문을 저장
- delete()
- 반영(flush)
- 현재 영속성 컨텍스트에 상태를 확인하여 SQL 생성 후 데이터베이스에 query를 전송
- 단, commit 전이기 때문에 데이터베이스에 실제로 저장되지 않은 상태
- flush()
✅영속성 컨텍스트에서 객체 관리
- EntityManager가 객체를 관리하고 배출하는 곳은 EntityManagerFactory 에서 나오고, 배출 되는 시점은 transaction이
시작 될 때이다. - 생성된 EntityManager는 스프링은 내부적으로 발행된 TransactionThread에 바인딩되기 때문에 해당 트랜잭션 동안
동일한 EntityManager 인스턴스를 재사용할 수 있게 된다.

✅영속성 컨텍스트의 특징
- 1차 캐시 & 동등성 보장
- 영속성 컨텍스트 내부에는 캐시라는 이름의 Map<@Id, Entity> 형태의 자료 구조가 존재
- 캐시는 동일 트랜잭션 내에서만 유효한 로컬 캐시
- 같은 엔티티를 반복 조회할 때, DB 접근 횟수를 줄여줌
- 실무 고려사항 : 대량의 데이터를 처리하는 배치 작업에서는 주기적으로 영속성 컨텍스트를 초기화 clear() 하여 메모리 사용량 관리 필요가 있어요. 다만 clear() 했다고해서 대량의 데이터가 stack memory에서 없어지는건 아니기 때문에 OutOfMemory를 조심해야해요.
- 쓰기 지연
- JPA는 SQL을 즉시 실행하지 않고 영속성 컨텍스트 내의 쓰기 지연 SQL 저장소에 모아둔다.
- transaction.commit() 시점에 모아둔 SQL을 한 번에 DB로 전송
- 작동 과정
1. em. persist(entity)호출 : 엔티티를 1차 캐시에 저장 + INSERT SQL 생성 후 쓰기 지연 SQL 저장소에 보관
2. transaction.commti() 호출 : flush() 자동 호출 > 쓰기 지연 SQL 저장소의 쿼리들을 DB에 전공 > 실제 커밋
- commit 전 flush()를 통해 DB에 반영되는 경우
- repository.flush() 직접 호출 시
- JPQL 쿼리 실행 전 (자동)
- 식별자 생성 전략이 GenerationType.IDENTITY인 경우 save() 호출 시 즉시 INSERT SQL 실행
- 변경 감지 (Dirty Checking)
- 트랜잭션 내에서 엔티티 값이 변경되면, 커밋 시점에 자동으로 UPDATE SQL이 생성
- 별도의 update() 메소드 호출이 필요 없는 것이 JPA의 큰 특징
- 변경 감지의 동장 원리
1. 트랜잭션 시작 시, 엔티티의 최초 상태 스냅샷을 저장
2. 플러시 시점에 현재 엔티티와 스냅샷을 비교 하여 변경된 엔티티 탐지
3. 변경된 엔티티가 있으면 UPDATE SQL 생성 후 DB에 전송
- 변경 감지 최적화 관점
- JPA는 기본적으로 엔티티의 모든 필드를 업데이트하는 SQL을 생성해요.
- 필드가 많은 엔티티의 경우 변경 필드만 업데이트하도록 설정 가능하죠.
'TIL > Spring' 카테고리의 다른 글
| <2025.05.08> TestCode - 단위 테스트 (0) | 2025.05.08 |
|---|---|
| <2025.05.07> 연관관계 N+1 (0) | 2025.05.07 |
| <2025.04.22> 배달 기능 프로젝트 피드백 (1) | 2025.04.22 |
| <2025.04.21> [Spring - advanced] 코드 개선 & 트러블 슈팅 (1) | 2025.04.21 |
| <2025.04.17> Formatter (0) | 2025.04.17 |