- 영속성 컨텍스트는 JPA를 이해하는데 있어 가장 중요한 개념이다.
- 영속성 컨텍스트는 애플리케이션에서 데이터베이스에 접근하기 전에 존재하는 공간 혹은 단계이다.
- DB로 가기 전 엔티티 객체를 관리하는 가상의 데이터베이스 정도로 이해하자.
- 비영속 상태
- 영속성 컨텍스트와 아무런 관계가 없는 상태이다.
- 단순히 객체가 생성된 상태이다.
- 영속 상태
- 영속성 컨텍스트에 의해 관리되는 상태이다.
- EntityManager의 persist메서드로 객체를 영속화 시킨다.
- 준영속 상태
- 이전에 영속성 컨텍스트에 저장되었던 객체가 영속성 컨텍스트에서 분리된 상태이다.
- 삭제
- 영속성 컨텍스트에서 객체를 삭제
- 1차 캐시
- 이름 그대로 캐싱의 효과를 볼 수 있다.
- 이전에 영속성 컨텍스트에 영속화 된 객체를 다시 한번 조회시 해당 객체가 영속 상태라면 DB에 쿼리를 날려 객체를 가져오는 것이 아니고, 1차 캐시에 캐싱된(영속화된) 객체를 가져온다.
- 영속성 컨텍스트의 생명주기가 생각보다 짧은 찰나이기에 성능상 엄청난 효과를 주진 못하지만 이해하고 사용해야 할 기능이다.
- 동일성 보장
- 영속성 컨텍스트에서 관리되는 객체를 반복적으로 조회하였을 때 조회된 객체의 동일성을 보장한다.
- 쓰기 지연
- 두 객체를 DB에 삽입한다고 해보자.
- em.persist(member1);
em.persist(member2);
transaction.commit();- 결과부터 말하자면 persist()하는 시점이 아닌 commit()하는 시점에 쿼리가 날라간다.
- 영속성 컨텍스트는 내부적으로 쓰기 지연 저장소를 가지고 이 저장소에 persist되는 객체를 분석하여 쿼리를 만들어 저장한다.
- 이후 커밋 시점에 쓰기 지연 저장소에 쌓인 쿼리를 한 번에 DB에 날린다.
- 더티 체킹 (변경 감지)
- JPA는 영속성 컨텍스트와 영속성 컨텍스트 내 객체의 관계를 마치 컬렉션과 컬렉션 내 데이터의 관계처럼 관리한다.
- 생각해보자. 컬렉션에 저장된 데이터를 변경해야 할 때, 변경하고 컬렉션에 다시 넣는 작업을 하는가??
- 하지 않는다. 컬렉션의 데이터를 변경하면 그것으로 끝이다. 당연하게 컬렉션에도 반영되는 것이다.
- JPA도 마찬가지이다. 영속성 컨텍스트에서 꺼내온 데이터를 수정 후에 다시 영속성 컨텍스트에 넣는 작업이 필요하지 않다. 어떻게??
- 영속성 컨텍스트는 1차 캐시 내의 객체가 최초 persist된 시점의 시냅샷을 저장한다.
- 이후 변경 작업이 끝나고 commit되는 시점에 스냅샷과 변경된 객체와 비교하여 변경에 해당하는 update쿼리를 생성하여 DB에 날리게 된다.
본 포스트는 김영한 님의 인프런 강좌를 수강 후에 정리한 내용입니다.