영속성 컨텍스트

김민지·2022년 10월 16일
0

JPA

목록 보기
4/27

용어 설명

엔티티

  • 엔티티는 영속성을 가진 객체로 DB 테이블에 보관할 대상입니다.

영속성

  • 데이터를 생성한 프로그램이 종료되어도 사라지지 않는 데이터의 특성을 말한다.
    영속성을 갖지 않으면 데이터는 메모리에서만 존재하게 되고 프로그램이 종료되면 해당 데이터는 모두 사라지게 된다.
    그래서 우리는 데이터를 파일이나 DB에 영구 저장함으로써 데이터에 영속성을 부여한다.

엔티티 매니저

  • 엔티티매니저는 영속 컨텍스트에 접근하여 엔티티에 대한 DB 작업을 제공합니다

영속성 컨텍스트

  • 엔티티를 영구 저장 하는 환경
    영속성 컨텍스트는 내부에 캐시를 가지고 있는데 이것을 1차 캐시라 합니다. 영속 상태의 엔티티는 모두 이곳에 저장됩니다. 쉽게 말해 영속성 컨텍스트 내부에 Map이 하나 있는데 (1차 캐시), 키는 @Id로 매핑한 식별자고 값은 엔티티 인스턴스입니다.
    애플리케이션과 데이터베이스 사이에서 객체를 보관하는 논리적 개념
    EntityManager를 통해서 영속성 컨텍스트에 접근
    EntityManager가 생성되면 논리적 개념인 영속성 컨텍스트(PersistenceContext)가 1:1 생성
  • 1차 캐시에서는 id, value가 key,value이기때문에 id에 대한 참조만이 가능해

비영속과 준영속의 차이

준영속 : 영속상태였다가 분리된 상태
비영속 : 영속상태에서 엔티티를 제거한 상태

  • 영속상태가 되기 위해서는 식별자가 꼭 필요하다 준영속상태의 엔티티는 무조건 id값을 가지고 있을 것이다.

영속성컨텍스트의 이점

동일성보장

변경감지 & 쓰기지연

엔티티 변경이 일어난 후, flush()가 발생하면 일어나는일들

  • flush는 디비와 영속성 컨텍스트를 같게 만들어주는 메서드임. 그래서 일단
    엔티티와 스냅샷을 비교해서 다르면 update sql을 생성하여 쓰기 지연 저장소에 넣어둠
    커밋시에 쓰기지연저장소의 쿼리들을 디비에 반영함

1차캐시

혼자 정리

영속성 컨텍스트에 대해서 설명을 해볼게요
영속성컨텍스트는 "엔티티를 영구저장하는 환경"입니다
1. 엔티티란 무엇인가?
-> 영속성을 가진 개체
2. 영속성이란 무엇인가?( = 영구저장하는 환경이 무엇을 뜻하는가?) 에 대해서 알아야해요
-> 그 개체를 생성시킨 프로그램이 종료되어도 데이터가 보존되는 특성
디비에 저장을 시키면 해당 프로그램이 종료되어도 데이터는 보존되겠죠

영속성컨텍스트는 이렇게 데이터베이스와 애플리케이션 사이에서 객체를 보관하는 논리적인 개념이에요

다음으로 엔티티 매니저에 대해서 설명할게요
엔티티매니저는 영속화된 객체들에 대해 여러 디비작업을 제공해줍니다.
1. 영속화된 객체가 무엇인가?
-> 영속성컨텍스트 개념은 영속, 비영속, 준영속에 대한 개념이 있어요
영속: 영속성컨텍스트에 의해 관리받고 있는 상태
준영속: 영속성컨텍스트에 의해 관리받고 있는 상태였다가 detached당한 상태
비영속: 영속성컨텍스트에 들어간적없는상태
이때의 영속상태인 객체를 의미해요
2. 여러 디비작업은 무엇인가?
-> save, update 이런 작업들을 중간에 대신 해주는거예요
다음으로 영속성 컨텍스트가 어떤 작업들을 하는지 알아볼게요

영속성 컨텍스트는
1. 변경감지
2. 쓰기지연
3. 동일성보장
4. 1차캐시
같은 기능을 제공해줍니다
먼저 1차캐시,
영속성 컨텍스트 내부에는 엔티티를 잠시 보관할수있는 저장소가 있는데 이를 1차캐시라고해요
네트워크를 통해 데이터베이스에 접근하는 시간 비용은 애플리케이션 서버에서 내부 메모리에 접근하는 시간 비용보다 수만에서 수십만 배 이상 비싸요.
따라서 조회환 데이터를 메모리에 잠시저장해서 데이터베이스 접근 횟수를 줄이면 애플이케이션 성능을 획기적으로 개선할 수 있어요
3번,
동일한 영속성 컨텍스트에서 같은 id값으로 조회해온 엔티티는 항상 주솟값이 같아요
1번과 2번은 같이 설명할게요
jpa에서는 update와 같은 메서드가 없어요 영속화된 객체 들이 변경되면 변경감지를 해서 update쿼리를 만들어주거든요
그과정을 이해하면 1번과 2번이 좀 이해가 돼요
예를들어
member = new Member;
em.persist(member);//영속성컨텍스트에 의해 관리받기 때문에
member.setName("새이름");
member.setName("두번째이름");
이메서드가 끝나면 커밋이 됩니다
그런데 커밋이 되기전에 flush가 돼요
flush가 일어나면서 아래와 같은 일들이 일어나는데요
1. 엔티티를 처음 등록할때의 스냅샷과 비교해서 변경된부분이 있으면 update쿼리를 만들음
2. 만들어서 쓰기지연저장소에 넣어둠
id생성전략이 identity가 아니라면 2번째줄에서 영속성컨텍스트에 저장이 되면서 쓰기지연저장소에 쿼리가 쌓입니다
그리고 세네번째줄에서는 아무일이 일어나지 않다가
flush때 member의 원래이름과 비교하여 두번째이름으로 변경되었으니 이에 대한 update쿼리를 만들고 만들어서
쓰기 지연 저장소에 넣어둬요


출처
https://dev-troh.tistory.com/m/151
https://hckcksrl.medium.com/%EC%98%81%EC%86%8D%EC%84%B1-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8-986464f8b1e8
https://velog.io/@devtel/JPA-%EC%98%81%EC%86%8D%EC%84%B1persistence%EC%9D%B4%EB%9E%80
https://velog.io/@seungho1216/JPA%EC%98%81%EC%86%8D%EC%84%B1-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B81%EC%B0%A8-%EC%BA%90%EC%8B%9C

profile
안녕하세요!

0개의 댓글