오늘은 JPA의 영속성 컨텍스트에 대해서 알아보려고 합니다.
JPA 의 영속성 컨텍스트 내부 구조와 동작 방식
- persist(엔티티) 를 실행하면 해당 엔티티 객체가 영속성 컨텍스트에서 관리되기 시작
- 1차 캐시라는 곳에 key 는 @Id(테이블의 기본키가 매핑된) 의 값, value는 해당 객체
- 바로 쿼리가 db 로 날아가는 것이 아니라, 해당 db 쿼리가 자동으로 만들어져서 쓰기 지연 저장소에 저장
- 트랜잭션 커밋이 실행되면 flush 라는 것이 실행되는데 이것은 쓰기 지연 저장소에 있는 쿼리를 DB 로 날려 변경 내용을 데이터베이스에 동기화하는 것
- 그리고 데이터베이스 커밋을 수행
- 4, 5 는 @Transactionl 이 붙은 메서드를 실행하면 자동적으로 실행
엔티티의 생명주기
위 영속성 컨테스트를 관리하는 것이 Entity Manager 인데, 이 엔티티 매니저는 엔티티의 생명주기를 관리합니다.
상태는 다음 4가지가 존재합니다.
- 비영속(New/Transient) : 영속성 컨텍스트가 관리하지 않음 (persist() 전 상태) == 순수 자바 객체
- 영속(Managed/Persistent) : 영속성 컨텍스트가 관리 (persist(), find() 후 상태) == 1차 캐시에 저장된 엔티티
- 준영속(Detached) : 영속 상태였지만 영속성 컨텍스트에서 분리 (detach(), clear(), close()) == 1차 캐시에서 삭제된 엔티티
- 삭제(Removed) : 삭제된 상태 (remove() 호출 후 commit()하면 DB에서 삭제)
변경감지
데이터를 조회하게 되면 엔티티가 영속 상태가 되는데, 이 상태가 되면 변경 감지 기능을 사용할 수 있습니다.
엔티티 매니저가 처음 객체를 영속화할 때, 이 최초 상태를 저장해두는데 이를 스냅샷 이라고 합니다.
그리고 플러시를 하는 시점에 엔티티 매니저가 초기 상태와 현재 상태를 비교해서 변경된 부분이 존재하면 이를 update 쿼리로 만들어서 쓰기 지연 저장소로 보냅니다.
정리하면
1. 트랜잭션 시작 (begin transaction)
2. 영속 상태 엔티티 조회 (`find()`)
3. 엔티티 필드 값 변경 (`setTitle()`)
4. `commit()` 실행 시:
- `flush()` 호출 (쓰기 지연 저장소에 SQL 반영)
- **변경 감지 실행 (변경된 엔티티 탐지)**
- **UPDATE SQL 자동 실행**
- 트랜잭션 커밋 (`commit()`)
'Server > Spring' 카테고리의 다른 글
[Spring Cloud] (0) | 2025.03.04 |
---|---|
@Transactional 에 대하여 (0) | 2025.02.24 |
HttpMessageConversionException 발생 원인과 해결책 알아보기 (0) | 2023.08.12 |