개발자로 후회없는 삶 살기
[문법] JPA 동작 원리 본문
서론
※ 과거에 기록한 내용에서 중요한 부분만 발췌하여 모두가 이해하기 쉽게 다시 서술한다.
본론
- 영속성 컨텍스트
JPA에서 가장 중요한 2가지는 엔터티와 테이블 매핑과 영속성 컨텍스트이다.
웹에서 고객 요청이 오면, 매니저 1, 2를 생성하고 매니저가 내부적으로 커낵션을 써서 db를 쓴다.
→ 영속성 컨텍스트란?
엔터티를 영구 저장하는 환경이다. JPA는 저장한다고 DB에 바로 넣는게 아니라, 컨텍스트에 저장한다.
매니저가 내부에 컨텍스트 공간을 가지고 있다.
- 엔터티 생명주기
1) 비영속
컨텍스트와 관련이 없는 상태이다.
2) 영속
컨텍스트에 객체를 관리하는 상태이다.
set까지는 비영속이고 persist를 하면 영속화된다.
persist는 뭐 하는 거야? ✅
JPA는 DB에 저장하는 게 아니라 우선 컨텍스트에 객체를 영속화한다. 그리고 트랜잭션 커밋되는 시점에, 엔터티 분석을 해서 DB에 쿼리가 날라간다.
- 영속화의 이점
→ 1차 캐시
컨텍스트는 내부적으로 1차 캐시를 가지고 있다. persist를 하면 1차 캐시에 저장된다.
캐시는 pk, 객체 키+벨류 형태이다. 이렇게 하면 조회에서 이점이 있다. JPA는 조회할 때 DB를 조회하지 않고 먼저 캐시를 조회한다.
멤버 2가 캐시에 없다고 가정한다. 먼저 캐시를 조회하고 없어서, DB에서 조회하고 캐시에 저장하고 반환한다. 이후 다음 조회에서는 DB를 조회하지 않는다.
🚨 큰 이점은 아니다.
컨텍스트는 트랜잭션 단위로 동작해서 고객 요청이 끝나면 트랜잭션이 종료할 때 1차 캐시도 종료해서 성능상 이점은 없다. 트랜잭션이 종료하면 컨텍스트도 삭제되어, 데이터가 보존되지 않는다.
DB에 저장한 상태에서 2번 조회해보면
1차 캐시에 없을 때 1번만 쿼리가 나간다. jpa는 같은 트랜잭션 안에서 영속화해서 1차 캐시에는 1개의 객체만 저장하니 == 비교를 보장한다.
→ 쓰기 지연
perst로 회원을 저장하고 바로 쿼리를 보내지 않고 쭉쭉 쌓고 커밋되는 순간에 db에 보낸다.
컨텍스트에 쓰기 지연 저장소가 있다. A를 쓰면, 1차 캐시에 들어가고 엔터티를 분석해서 sql을 만들어서 저장한다. 이때까지 db에 들어가는게 없고 커밋 시점에 저장소를 flush 해서 db에 쿼리가 날라가고 커밋된다. 트랜잭션이 끝나면 이전에 캐시에 넣어둔 데이터는 없다.
왜 굳이 이렇게 할까? ✅
어플리케이션 성능에는 한 번만 쿼리를 보내는게 좋다. 버퍼링 기능이 가능하여 배치 사이즈만큼 한번에 쿼리를 발생시킨다.
→ 엔터티 수정 변경 감지
set만 해도 update 쿼리가 날라간다. 수정 메서드가 없이도 객체가 수정된다.
jpa는 커밋을 하는 순간에 엔터티와 스냅샷을 비교한다. 스냅샷은 엔터티를 저장한 최초 시점 기준으로, 커밋 시점에 실제 엔터티와 스냅샷을 비교해서 다르면 update 쿼리를 저장소에 넣고 db에 보내고 커밋한다.
※ 엔터티 삭제 : 객체가 삭제됐으면 커밋 시점에 delete 쿼리가 나간다.
- 플러시
컨텍스트 변경 내용을 db와 동기화하는 것으로, 커밋할 때 플러시가 나간다.
→ 하는법
테스트를 위해 방법을 알아야 한다.
1. flush
저장해도 커밋 전에는 쿼리가 없다고 했는데
flush를 하면 그 즉시, 변경 감지, sql 저장, db에 쿼리 전송이 일어난다. 커밋 전에 쿼리를 볼 수 있다. 플러시를 하면 1차 캐시가 다 지원지는게 아니고 위 3가지 동작만 일어난다.
2. jpql 실행
jpql 실행 시 플러시가 되는 이유는 jpql은 보통 조회 쿼리를 작성할 텐데 그래서 개발자의 의도대로 동작하도록 하기 위해 db와 영속성 컨텍스트를 동기화한다.
- 준영속 상태로 만드는 법
persist나 find를 해서 영속화를 했는데 이를 컨텍스트에서 분리할 수 있고 그러면 변경 감지나 동기화가 불가능하다.
1. detach
커밋하면 쿼리가 나가야하는데
조회 쿼리 이후 수정 쿼리가 없다.
2. clear
clear나 close를 하면 컨텍스트를 아예 삭제해버린다. find하고 clear하고 find하면 1차 캐시가 없어져서 조회 쿼리가 두번 나간다.
'[백엔드] > [JPA | 학습기록]' 카테고리의 다른 글
[문법] 연관관계 매핑 시 고려사항 (0) | 2024.08.11 |
---|---|
[문법] 다양한 연관관계 매핑 (3) | 2024.08.10 |
JPA PART.프록시와 연관관계 관리 (0) | 2023.08.22 |
JPA PART.고급 매핑 (0) | 2023.08.20 |
JPA PART.다양한 연관관계 매핑 (0) | 2023.08.17 |