영속성 컨텍스트란?
- "엔티티를 영구 저장하는 환경"
- EntityManager.persist(entity) : db에 저장하는 것이 아닌 영속성 컨텍스트에 저장한다는 의미
- 논리적인 개념으로 EntityManager를 통해 접근한다.
- EntityManager를 생성할 때 하나 만들어진다.
em.persist(member);
** 엔티티 메니저를 사용하여 회원 엔티티를 영속성 컨텍스트에 저장하는 코드
엔티티의 생명주기
- 비영속(new/transient) : 새로운 상태(new), 영속성 컨텍스트와 관계가 없다.
Member member = new Member();
- 영속(managed) : 영속성 컨텍스트에 관리되는 상태, DB에 저장되지는 않는다.
em.persist(member);
- 준영속(detached) : 영속성 컨텍스트에 저장되었다 분리, 어떤 기능도 동작하지 않는다.
em.detach(member);
// 영속성 컨텍스트를 비우거나 종료해도 엔티티는 준영속 상태
em.clear();
em.close();
- 삭제(removed) : 영속성 컨텍스트와 데이터베이스에서 엔티티를 삭제
em.remove(member);
<영속성 컨텍스트의 이점>
1차 캐시(조회)
- 영속성 컨텍스트 내부의 캐시
- 엔티티 조회 시 1차 캐시에 저장했다가 가져옴
- 1차 캐시 : 키 - 식별자 값(pk), 값 - 엔티티 인스턴스
Member member = em.find(Member.class, "member");
영속 엔티티의 동일성 보장
- 1차 캐시로 반복 가능한 읽기 등급의 트랜잭션 격리 수준을 애플리케이션 차원에서 제공
- 두 객체 간 동일성 비교가 가능
트랜잭션을 지원하는 쓰기 지연(등록)
- em.persist(entity); 를 통해 1차 캐시에 저장 (db에 보내지 않는다)
- 커밋하기 직전까지 내부의 쿼리 저장소에 insert sql을 모아둔다.
- 커밋하는 순간 sql 실행
엔티티 변경 감지 (더티 체킹) (수정)
- em.update(entity)/ em.persist(emtity)를 쓸 필요가 없다.
- 값을 바꾸면 자동으로 update 쿼리를 실행한다.
- 영속 상태의 엔티티일 경우 적용된다.
1. flush()
2. 엔티티와 스냅샷 비교
3. 값이 바뀌었으면 쓰기지연 sql 저장소에 update 쿼리 생성
4. db 반영
지연 로딩
플러시
: 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영. 보통 커밋될 때 발생한다.
1. 변경 감지 (dirty checking)
2. 수정 엔티티를 쓰기 지연 sql 저장소에 등록
3. 쓰기 지연 sql 저장소의 쿼리를 데이터베이스에 전송
이 작업들이 수행된다.
영속성 컨텍스트를 플러시하는 방법
- em.flush() - 직접 호출
- 트랜잭션 커밋 - 자동 호출
- jpql 쿼리 실행 - 자동 호출 (sql로 바로 실행되기 때문)
** 플러시를 한다고 해서 1차 캐시가 지워지지는 않는다.
** 영속성 컨텍스트를 비우는 것이 아니라 변경 내용을 db에 동기화 하는 것이다.
** 트랜잭션의 개념이 있기 때문에 중요한 것! -> 커밋 직전에만 동기화하면 된다.
(jpa는 동시성에 대한 부분은 다 db에 위임한다.)
플러시 모드 옵션
em.setFlushMode(FlushModeType.COMMIT)
- FlushModeType.AUTO : 쿼리와 플러시 반복 수행 (기본 설정)
- FlushModeType.COMMIT : 커밋 시에만 플러시 (쿼리 실행은 x)
준영속 상태
영속 상태의 엔티티가 영속성 컨텍스트에서 분리되는 것 (detached)으로 영속성 컨텍스트가 제공하는 기능을 사용하지 못한다.
- em.detach(entity) : 특정 엔티티만 준영속 상태로 전환
- em.clear() : 영속성 컨텍스트를 초기화
- em.close() : 영속성 컨텍스트를 종료
'컴퓨터 > JPA' 카테고리의 다른 글
[자바 ORM 표준 JPA 프로그래밍] - 엔티티 매핑 (0) | 2023.10.05 |
---|