23.02.11

Kuno17·2023년 2월 13일
0

TIL/WIL

목록 보기
19/38
post-thumbnail

study

영속성 컨택스트 장점과 원리


영속성 컨택스트

영속성 컨택스트란 엔티티를 영구 저장하는 환경이라는 뜻을 말한다.
영속성 컨택스트는 엔티티 매니저를 통해 엔티티를 조회하거나 저장할때 엔티티를 보관,관리 한다.

엔티티의 생명주기

  1. 비영속
    영속성 컨택스트와 관계가 없는 새로운 상태
// 엔티티를 생성
Member member = new Member();
member.setId("member1"); 
member.setUsername("회원1");
  1. 영속.
    엔티티 매니저를 통해 엔티티가 영속성 컨택스트에 저장되어 관리되고 있는 상태
// 엔티티 매니저를 통해 영속성 컨텍스트에 엔티티를 저장
em.persist(entity);
  1. 준영속
영속성 컨텍스트에서 관리되다가 분리된 상태
// 엔티티를 영속성 컨택스트에서 분리
em.detach(entity);
// 영속성 컨텍스트를 비우기
em.clear();
// 영속성 컨택스트를 종료
em.close();
  1. 삭제
    영속성 컨택스트에서 삭제된 상태
em.remove(entity)

영속성 컨택스트의 장점

1. 1차 캐시

영속성 컨택스트에는 1차 캐시가 존재한다. 엔티티를 영속성 컨택스트에 저장하는 순간 1차캐시에 객체가 key(id),value(entity)값으로 저장.

엔티티 매니저가 조회를 할때 먼저 영속성 컨택스트에 있는 1차캐시에서 해당 엔티티를 조회, 있는 경우 DB접근 하지않고 반환.
없는 경우 엔티티 매니저가 em.flush()할때에 DB에 접근해서 엔티티를 꺼내고 이를 1차캐시에 저장.

2. 동일성 보장(Identity)

영속성 컨택스트에서 꺼내온 객체는 동일성이 보장된다. 같은 엔티티를 두번 조회할 경우 두개의 엔티티는 동일한 엔티티이다.
1차 캐시로 반복가능한 읽기(REPEATABLE READ)등급의 트랜잭션 격리 수준을 DB가 아닌 애플리케이션 차원에서 제공한다.

Member member1 = em.find(Member.class, "member1");
Member member2 = em.find(Member.class, "member1");
System.out.println(member1 == member2) => true
  • 트랜잭션을 지원하는 쓰기 지연

    트랜잭션 내부에서 persist()가 일어날 때, 엔티티들을 1차 캐시에 저장하고, 쓰기지연 SQL저장소에 INSERT쿼리들을 생성해서 쌓아 높는다.
    DB에 바로 넣지않고 기다린다.
    commit()또는 flush()를 할때 쓰기지연 SQL저장소에 저장되어있는 SQL들을 DB에 보낸다.
EntityManager em = emf.createEntityManager(); 
EntityTransaction transaction = em.getTransaction(); 
//엔티티 매니저는 데이터 변경시 트랜잭션을 시작해야 한다. 
transaction.begin(); // [트랜잭션] 시작 
em.persist(memberA);
em.persist(memberB); 
//여기까지 INSERT SQL을 데이터베이스에 보내지 않는다. 
//커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다. 
transaction.commit(); // [트랜잭션] 커밋

3. 변경감지(DirtyChecking)

JPA에서는 엔티티를 업데이트할때 update(), persist()와 같은 메소드로 영속성 컨택스트에 알려주지 않아도 된다.
이것이 가능한 이유는 변경감지(DirtyChecking)덕분이다.
엔티티 매니저가 엔티티를 1차캐시에 저장할때 스냅샷도 같이 저장된다. 트랜잭션이 커밋하는 시점에서 엔티티와 스냅샷을 비교해 변경사항이 있으면
UpdateSQL을 알아서 생성해 쓰기지연 저장소에 SQL을 저장한다.

4.플러시

플러시는 영속성 컨택스트의 변경내용을 DB에 반영한다.
트랜잭션 커밋시점에서 플러시가 발생하는대 이때 쓰기지연 저장소에 쌓여있는 SQL문들을 DB에 전송한다.
플러시는 영속성 컨택스트를 비우는것이 아니다. 쌓여있는 SQL문들을 DB로 전송하는것 뿐이다.

영속성 컨택스트를 플러시 하는방법

1.em.flusgh() 직접호출
2.트랜잭션 커밋(플러시 자동호출)
3.JPQL 쿼리 실행(플러시 자동호출)

후기

아직 정확한 내용을 파악한것은 아니나 영속성 컨택스트가 어떤일을 하는지 어렴풋하게 알 수 있는 공부였다.

profile
자바 스터디 정리 - 하단 홈 버튼 참조.

0개의 댓글