영속성 컨텍스트 란?
- entity를 영구 저장하는 환경
- JPA를 이해하기 위해 중요한 용어
- entityManager를 통해서 영속성 컨텍스트에 접근 > 쉽게 entityManager 안에 영속성 컨텍스트라는 눈에 보이지 않는 공간이 생긴다고 이해!
EntityManager.persist(entity); // entity(객체)를 영속성 컨텍스트라는 공간에 저장!
엔티티의 생명 주기
- 비영속 (new/transient) : 영속성 컨텍스트에 추가되지 않은! 관계가 없는 새로운 상태 -> 새로운 객체 생성 때 상태
- 영속 (managed) : 영속성 컨텍스트에 관리되는 상태
- 준영속 (detached) : 영속성 컨텍스트에 저장되었다가 분리된 상태 > 영속성 컨텍스트가 제공하는 기능을 사용 못함
- 삭제 (removed) : 삭제된 상태 > DB 삭제 쿼리로 이어짐
영속성 컨텍스트의 이점
- 1차 캐시 : 객체 조회 시, 캐시에 존재하는 entity의 경우 db로 쿼리를 날리지 않는다. > transaction 마다 entityManager를 새로 생성하기 때문에 큰 도움은 되지 않느다.
- 동일성 보장 : 동일한 객체를 조회 시, 동일성 비교에서 true를 확인할 수 있다.
- 트랜잭션을 지원하는 쓰기 지원 : persist 마다 DB에 쿼리를 전송하는 것이 아니라 영속 컨텍스트 내 쓰기 지연 SQL 저장소에 보낼 쿼리를 모은다. 그 후, transaction.commit()을 호출하면 해당 쿼리들을 flush 시키고 commit 한다.
- 변경 감지 (Dirty Checking) : 엔티티 값을 처음 읽어온 시점을 스냅샷으로 저장한다. 그 후, flush가 호출되면 스냅샷과 1차 캐시에 저장된 entity를 비교하여 변경된 사항이 있을 경우, update 쿼리를 쓰기 지연 저장소에 저장한다. 이에 객체 내용을 변경 후, 별다른 호출 없이 commit()하는 것 만으로 수정사항이 DB에 반영된다.
Flush : 플러시
- 영속성 컨텍스트의 변경 내용을 데이터 베이스에 반영한다. (동기화)
- 역할 : 변경 감지, 수정된 entity 쓰기 전연 SQL 저장소에 등록, 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송
- 보통 transcation.commit()호출 시 자동으로 호출되지만, flush()를 직접 호출할 수도 있다.
- JPQL 쿼리 실행에도 자동으로 플러시가 호출된다.
- 플러시 모드에는 AUTO와 COMMIT이 있는데 DEFAULT는 AUTO다
- AUTO : 커밋이나 쿼리를 실행할 때 플러시 / COMMIT : 커밋할 때 만 플러시
- 영속성 컨텍스트를 비우지 않음!
참고
- 인프런 : 자바 ORM 표준 JPA 프로그래밍 - 기본편 강의