2021. 7. 24. 21:56ㆍJPA
JPA의 가장 핵심인 영속성 컨텍스트에 대해 다뤄보겠습니다.
영속성 컨텍스트란?(Persistence Context)
영속성 컨텍스트는 '엔티티를 영구 저장하는 환경'입니다.
영속성이란 '오래 계속되는 성질'을 말하고 context는 '저장소'의 의미를 가집니다.
한 트랜잭션내에서 다루는 엔티티들에 관련된 쿼리문들을 영속성 컨텍스트라는 일종의 Buffer에 오래 모아두었다가 Commit 시점에 한꺼번에 처리하기 때문에 이런 이름을 갖게 된 것 같습니다.
JPA에서 아래의 코드를 실행하면 DB에 알아서 INSERT 쿼리문을 만들어서 날렸는데,
이는 사실 '엔티티를 영속성 컨텍스트에 저장하겠다'라는 의미입니다.
entityManager.persist(entity);
엔티티의 생명주기
- 비영속(new / transient)
- 영속(managed)
- 준영속(detached)
- 삭제(removed)
1. 비영속
비영속 상태는 객체를 생성만 한 상태입니다. JPA와 아직 관련되지 않은 상태입니다.
Member member = new Member();
member.setName("철수");
2. 영속
EntityManager 인터페이스의 메서드를 호출해서 매개변수에 객체를 넣은 상태입니다.
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityTransaction tx = em.getTransaction();
tx.begin(); // 트랜잭션 시작
EntityManager em = emf.createEntityManager(); // EntityManager 생성
Member member = new Member(); // 객체 생성
member.setName("철수");
em.persist(member); // 영속성 컨텍스트에 객체 저장
tx.commit(); // 트랜잭션 종료
3. 준영속
저장했던 객체를 영속성 컨텍스트에서 분리시킨 상태입니다.
em.detach(member);
4. 삭제
객체를 삭제한 상태입니다.
em.remove(member);
영속성 컨텍스트의 이점
- 1차 캐시
- 동일성 보장
- 트랜잭션을 지원하는 쓰기 지연
- 변경 감지
엔티티 조회, 1차 캐시
한 트랜잭션내에서 DB를 조회하면 영속성 컨텍스트의 1차 캐시에 저장되고, 같은 조회 동작이 발생하면 DB를 Searching하기 전에 1차 캐시를 먼저 Searching하고 캐시 히트시 DB에 쿼리를 날리지 않습니다.
하지만 성능 향상은 그리 크지 않습니다.
그 이유는 1차 캐시가 한 트랜잭션 동안만 유지되므로 비즈니스 로직이 엄청 길지 않은 이상 1차 캐시가 그리 오래 유지 되지 않기 때문입니다.
동일성 보장
영속 컨텍스트안의 엔티티 객체는 == 비교를 통해 동일성이 보장됩니다.
엔티티 추가, 트랜잭션을 지원하는 쓰기 지연(버퍼링)
EntityManager의 함수를 호출할 때마다 SQL 버퍼에 쿼리문이 차곡차곡 쌓이고 commit 하는 순간 한번에 flush하여 DB를 동기화 합니다.
SQL 버퍼의 크기 persistence.xml 설정 파일에 아래의 속성으로 조절 할 수 있습니다.
<property name="hibernate.hibernate.jdbc.batch-size" value="5"/>
변경 감지
영속성 컨텍스트에 등록된 객체의 수정이 이루어지면 개발자가 따로 update 함수를 호출할 필요 없이, JPA가 알아서 변경된 내용을 감지하여 update 쿼리를 날립니다.
정확히는 commit 시점에 flush()가 호출되고 1차 캐시에 등록된 각 객체의 스냅샷을 비교해서 변경이 있는 객체를 알아서 DB에 업데이트합니다.
스탭샷은 1차 캐시에 추가된 시점의 객체 데이터를 저장한 데이터입니다.
이를 통해 기존의 복잡한 update 로직을 짜는 과정에서 인간의 실수 요소를 줄일 수 있게 되었습니다.
플러시(flush)
flush()는 커밋시점에 자동 호출되고 영속성 컨텍스트의 변경 내용을 DB에 반영하는 함수입니다.
flush()를 호출 -> 변경을 감지 -> 수정 SQL을 쓰기 지연 SQL 버퍼에 등록 -> SQL 버퍼를 DB에 한꺼번에 전송
순으로 진행됩니다.
flush는 영속성 컨텍스트의 변경 내용을 DB에 동기화하는 것이기 때문에 강제 호출해도 영속성 컨텍스트가 비워지지 않습니다.
flush의 호출 방법은 아래와 같습니다.
- em.flush() - 직접 호출
- tx.commit() - 자동 호출
- JPQL 쿼리 실행 - 자동 호출
준영속 상태 관련 함수
특정 엔티티만 준영속 상태로 만들기
em.detach(entity); // 1차 캐시에 특정 엔티티 지움
모든 엔티티를 준영속 상태로 만들기
em.clear(); // 1차 캐시 비우기
영속성 컨텍스트 종료하기
em.close(); // 자원 회수
Ref.
https://www.inflearn.com/course/ORM-JPA-Basic
자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 | 강의
JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다., 본 강의는 자바 백엔
www.inflearn.com
'JPA' 카테고리의 다른 글
[JPA] 엔티티 매핑 (0) | 2021.07.30 |
---|---|
[JPA] JPA 시작하기 (2) | 2021.07.23 |
[JPA] JPA란? (0) | 2021.07.22 |