JPA 에서 가장 중요한 2가지를 꼽으면
- 영속성 컨텍스트
- 객체와 관계형 데이터 베이스 간의 연관관계 맵핑 두가지 일 것 이다 .
영속성 컨텍스트에 대해서 먼저알아보자
영속성 컨택스트
클라이언트의 요청이 들어올 때 EntityManagerFactory가 각 쓰레드마다 EntityManager를 생성하고 EntityManager는 DB의
connectionpool에 접근하여 데이터를 처리한다. EntityManager가 생성되면서 영속성 컨텍스트가 1:1로 생성되는데 EntityManager는 DB에 바로 접근하는 것이아니라 영속성 컨텍스트에 접근하여 해당 데이터를 관리한다.
EntityManager에서 persist() 메서드를 호출한다는 것은 DB에 데이터를 저장하는 것이 아니라 영속성컨텍스트에 저장한다는 뜻이다.
엔티티의 생명주기
엔티티는 4가지 상태를 갖게 된다.
1. 비영속 (new/transient) 상태
영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
2.영속(managed)
영속성 컨텍스트에 관리되는 상태
3. 준영속(detached)
영속성 컨텍스트에 저장되었다가 분리된 상태
4.삭제 (removed)
삭제된 상태
영속성 컨텍스트의 이점
1. 1차캐시
예를 들어 Member(Long id, String name) 라는 엔티티를 생성하고 persist()를 하여 영속 상태로 만든다고 생각해보자
해당 엔티티는 영속성 컨텍스트의 올라가게 되고 엔티티의 @id에 설정한 PK값과 , 저장한 엔티티 객체가 1차 캐시에 저장된다
그림으로 보면 아래와 같다
entitymanager 의 find() 등의 조회 메서드를 사용할 때 1차 캐시에서 키값을 비교해 조회하고
만약 존재한다면 캐시에 있는 것을 바로 조회하기 떄문에 DB까지 가지 않아도 된다는 장점이 있다 .
중요한 점은 1차캐시에 존재하지 않을 경우이다 이 경우에는 DB에서 값을 찾고 DB에 있는 값을 1차 캐시에 저장하고 반환한다.
1. find()로 엔티티를 1차캐시에서 찾는다
2. 없다면 DB로 들어간다.
3. DB에서 값을 조회하고 조회된 데이터를 1차캐시에 저장한다 .
4. 반환한다.
하지만 위와 같은 과정은 하나의 요청에 관해서만 생겨나는 일이기 때문에 간단한 로직일 경우 크게 이점은 없다 .
2. 쓰기 지연 SQL 저장소
위에서 말한 것처럼 persist() 메서드가 호출되면 엔티티가 1차 캐시에 올라가는데 이때 동시에 해당 엔티티를 분석하여
SQL을 생성하여 영속성 컨텍스트의 쓰기 지연 SQL 저장소라는 곳에 저장을 하고 트랜젝션이 commit 되는 시점에 한번에 DB로 SQL이 flush() 된다 .
3. 변경 감지(Dirty checking)
데이터 변경시에 일어나는 기능이다.
위에 말한 1차 캐시에는 사실 1가지가 더 저장된다 바로 1차 캐시에 들어온 시점의 엔티티의 스냅샷이다 .
JPA에서 데이터베이스 트랜젝션 커밋이 일어날때 flush()가 호출되면 1차캐시에 저장된 엔티티 스냅샷과 flush 되는 시점의 엔티티를 비교하고 변경된 사항이 있다면 update 쿼리를 만들어 쓰기 지연 저장소에 저장한 후에 flush()로 쿼리를 날린다.
순서로 보면
트랜젝션 시작 - > 로직 수행 - > flush 호출 () -> 1차캐시에서 스냅샷과 현재 엔티티를 비교 -> 변경 감지되면 업데이트쿼리 생성 후 쓰기지연 저장소 저장->->flush 수행 -> 트랜젝션 커밋
4.flush()
변경 감지 , 수정된 엔티티 쓰기 지연 sql 저장소에 등록 , 저장소에 저장된 쿼릴르 데이터베이스에 전송. 역할을 한다.
flush가 호출 된다고 트랜젝션이 커밋되는 것은 아니다 .
'JPA' 카테고리의 다른 글
JPA 공부 3 - 연관관계 매핑2 양방향 연관관계와 연관관계 주인 (0) | 2021.06.04 |
---|---|
JPA 공부 2 - 연관관계 매핑 1 단방향 연관관계 (0) | 2021.06.03 |
Springboot- JPA 페이징처리 (0) | 2020.11.20 |
JPA 패치조인 활용 (0) | 2020.11.13 |
SPRING - JPA를 활용한 API 개발 ( 권장하는 방법 ) (0) | 2020.11.13 |