영속성 컨텍스트는 엔티티를 영구 저장하는 환경이라는 뜻. 엔티티 매니저를 통해 접근할 수 있다.
엔티티의 생명주기
비영속
영속
준영속
삭제
영속성 컨텍스트의 이점
조회시에 1차캐시를 조회-> 캐시에 있으면 캐시에 있는 값을 바로 반환
->캐시에 없으면 DB조회 후 1차캐시에 저장 후 객체반환
(그런데, 1차캐시는 한 트랜잭션 내에서만 유효하기때문에 성능상 약간의 이점을 갖는다)
영속 엔티티의 동일성 보장
똑같은 객체를 각각 find한 후, 두 객체를 비교하면 true가 나옴.
같은 트랜잭션 내에서 같은 객체는 동일하다.
트랜잭션을 지원하는 쓰기 지연
영속 컨텍스트 내에는 1차캐시 외에 쓰기 지연 SQL저장소가 있다.
어떤 객체를 영속하면 JPA가 객체를 분석해서 insert 쿼리를 만들어 쓰기 지연 SQL저장소에 SQL을 저장한다.
이후 트랜잭션 커밋시점 flush가 일어나면서 쿼리가 실행된다.
이렇게 함으로써 버퍼링을 통해 쿼리 최적화를 하게됨.
엔티티 수정 변경감지
커밋시점 flush()가 호출되는데, 이때 엔티티와 스냅샷을 비교한다.(스냅샷: 1차캐시에 들어온 최초상태의 값)
변경이 있다면 쓰기지연 SQL저장소에 update SQL을 생성해두고, 트랜잭션 커밋시점에 실행됨.
플러시
영속성 컨텍스트의 변경내용을 데이터베이스에 반영.
영속성 컨텍스트를 플러시하는 방법
em.flush() 직접호출
트랜잭션 커밋
JPQL쿼리 실행
(참고: JPA를 이용하기 위해서 엔티티에는 기본생성자가 있어야한다.)
준영속상태
1차캐시에 올라가는, 영속상태가 되는 방법은 em.persist, em.find를 이용하면 된다.
영속성 컨텍스트에 올라간 객체를 빼고싶다면?
=준영속상태로 만들기 위한 방법은 em.detach(객체), em.clear(), em.close()가 있다.
영속성 컨텍스트
영속성 컨텍스트는 '엔티티를 영구 저장하는 환경'이라고 표현할 수 있다. 이는 데이터베이스와 애플리케이션 사이에서 엔티티를 보관하고 관리하는 가상의 데이터베이스 같은 역할을 한다. 이 환경에 접근하기 위해서는 엔티티 매니저를 사용한다.
엔티티의 생명 주기
엔티티의 생명 주기는 '비영속', '영속', '준영속', '삭제'의 단계로 나뉜다. 비영속은 아직 영속성 컨텍스트나 데이터베이스와 연관이 없는 상태를, 영속은 영속성 컨텍스트에 저장된 상태를, 준영속은 영속성 컨텍스트에서 분리된 상태를, 그리고 삭제는 엔티티를 영구히 제거한 상태를 의미한다.
영속성 컨텍스트의 이점
영속성 컨텍스트가 주는 이점들은 아래와 같다:
1. 1차 캐시 조회: 영속성 컨텍스트는 내부에 1차 캐시를 가지고 있다. 엔티티를 조회할 때 먼저 이 1차 캐시를 확인한다. 만약 캐시에 엔티티가 있다면, DB를 조회하지 않고 바로 반환한다. 캐시에 없다면, DB를 조회한 후, 그 결과를 1차 캐시에 저장하고, 해당 엔티티를 반환한다. 하지만 이 1차 캐시는 한 트랜잭션 내에서만 유효하기 때문에 전체 성능 향상에는 크게 기여하지 않는다.
2. 영속 엔티티의 동일성 보장: 같은 엔티티를 두 번 find한 후 두 객체를 비교하면, 결과는 true가 반환된다. 같은 트랜잭션 내에서는 동일한 엔티티에 대해 항상 같은 객체를 반환하기 때문에 동일성이 보장된다.
3. 트랜잭션을 지원하는 쓰기 지연: 영속성 컨텍스트는 내부에 쓰기 지연 SQL 저장소를 가지고 있다. 엔티티를 영속화하면 JPA는 insert SQL을 만들어 쓰기 지연 SQL 저장소에 저장해 둔다. 트랜잭션을 커밋하는 시점에 저장된 쿼리를 DB에 전송하여 실행된다. 이 과정을 통해 DB 액세스 횟수를 줄여 성능을 최적화할 수 있다.
4. 엔티티 수정 변경 감지: 트랜잭션 커밋 시점에 영속성 컨텍스트는 flush를 실행하며, 이때 영속 엔티티와 스냅샷(1차 캐시에 들어온 엔티티의 초기 상태)을 비교한다. 변경된 엔티티가 있다면, 쓰기 지연 SQL 저장소에 update SQL을 생성해두고, 이 SQL도 트랜잭션 커밋 시점에 DB에 전송한다.
플러시
'플러시'라는 용어는 영속성 컨텍스트의 변경 사항을 데이터베이스에 반영하는 과정을 의미한다. 영속성 컨텍스트를 플러시하는 방법은 크게 세 가지가 있다: em.flush()를 직접 호출하는 방법, 트랜잭션을 커밋하는 방법, 그리고 JPQL 쿼리를 실행하는 방법이다.
엔티티 클래스 기본 생성자가 필요하다
JPA를 사용하려면 엔티티 클래스에 기본 생성자가 반드시 있어야 한다는 점을 명심하자. JPA 구현체는 리플렉션을 이용해 엔티티 객체를 생성하는데, 이때 기본 생성자가 사용된다.
준영속 상태
준영속 상태란 영속성 컨텍스트에서 관리되던 영속 상태의 엔티티가 영속성 컨텍스트와 더 이상 연결되지 않는 상태를 의미한다. 영속성 컨텍스트에서 엔티티를 분리하려면 em.detach(엔티티), em.clear(), 또는 em.close()를 사용하면 된다. 이러한 준영속 상태의 엔티티는 영속성 컨텍스트의 관리를 받지 않으므로, 엔티티를 변경해도 데이터베이스에 반영되지 않는다.
댓글