엔티티를 영구 저장하는 환경이다. 일반적으로 트랜젝션 단위로 생성하고 트랜젝션이 종료하면 지운다.
entityManager.persist(entity); --> 엔티티 매니저를 통해 영속성 컨텍스트에 접근
• 비영속 (new/transient)
영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
• 영속 (managed)
영속성 컨텍스트에 관리되는 상태
transaction을 commit하는 시점에 query가 발생한다.
• 준영속 (detached)
영속성 컨텍스트에 저장되었다가 분리된 상태
• 삭제 (removed)
삭제된 상태
• 1차 캐시
db 조회 전 1차캐시에서 먼저 확인한다. 영속성 컨텍스트가 영속 상태인 찰나의 순간에 캐시를 활용하는거라 성능 향상효과는 미비하다.
• 동일성(identity) 보장
애플리케이션 차원에서 DB에서 불러온 객체의 동일성을 보장한다. 같은 트랜젝션 안에서 DB에서 불러와 생성된 객체의 값을 == 비교 시 같다고 나온다.(자바에서는 같은 데이터의 객체를 두개 만들어도 주소 값이 다르기 때문에 == 비교시 다르게 나옴)
• 트랜잭션을 지원하는 쓰기 지연
트랜잭션 안에서 커밋 시점까지 쿼리 요청을 미룬다.
(transactional write-behind)
• 변경 감지(Dirty Checking)
영속 엔티티 조회 후 데이터 수정 시 커밋이 나갈때, flush() 호출 후 엔티티와 엔티티가 처음 불렸을때 생성한 스냅샷을 비교한다. 변경 값이 발생하였다면 update sql이 영속성 컨텍스트 내부적으로 발생 후 커밋이 이루어진다.
• 지연 로딩(Lazy Loading)
영속성 컨텍스트의 변경내용을 테이터베이스에 반영한다. 영속성 컨텍스트를 비우는것은 아니고 내부의 변경내용을 DB에 동기화 하는것이기 때문에 트랜잭션 작업 단위에서 커밋 직전에 동기화 하는것이라고 이해하면 된다.
플러시 발생 시,
변경 감지
수정된 엔티티 쓰기 지연 SQL 저장소에 등록
쓰기 지연 SQL 저장소의 쿼리를 DB에 전송(등록, 수정, 삭제)
1차 캐시는 전부 유지된다.
플러시 방법
• em.flush() - 직접 호출
• 트랜잭션 커밋 - 플러시 자동 호출
• JPQL 쿼리 실행 - 플러시 자동 호출
플러시 모드 옵션
• FlushModeType.AUTO
커밋이나 쿼리를 실행할 때 플러시 (기본값)
• FlushModeType.COMMIT
커밋할 때만 플러시
영속 상태의 엔티티가 영속성 컨텍스트에서 분리되는 것으로 영속성 컨텍스트가 제공하는 기능을 사용하지 못한다.
준영속 상태로 만드는 방법
• em.detach(entity)
특정 엔티티만 준영속 상태로 전환
• em.clear()
영속성 컨텍스트를 완전히 초기화
• em.close()
영속성 컨텍스트를 종료