본문 바로가기
개발 이론/JPA

영속성 컨텍스트와 트랜젝션

by dal_been 2023. 12. 29.
728x90

이 부분이 계속 헷갈려서 약 1주간 방황하다..역시 jpa 김영한님의 책을 보고 어느정도 정리되었다.

 

Entity Manager

 

엔티티 매니저는 엔티티를 저장, 수정, 삭제, 조회하는 등 엔티티와 관련딘 모든 일을 처리한다.

즉 가상의 데이터 베이스라고 생각하면 된다.

 

다만 엔티티 매니저는 여러 스레드가 동시에 접그하면 동시성 문제가 발생하므로 스레드간의 절대 공유해서는 안된다.

 

 

궁금증 ) 엔티티 매니저의 경우 가상의 데이터베이스라고 했는데 그럼 실제 데이터베이스의 연결을 지속하는가??

아니다. 필요한 시점에서 커넥션을 얻는다. 즉 보통 트랜젝션을 시작할때 커넥션을 획득한다

 

영속성 컨텍스트

 

엔티티를 영구 저장하는 환경이다.

엔티티 매니저를 생성할때 하나의 영속성 컨텍스트가 만들어진다.

 

  • 엔티티 매니저가 자신의 역할을 수행할때(저장,수정, 삭제, 조회) 엔티티를 보관하고 관리하는 곳이 영속성 컨텍스트다
  • 영속성 컨텍스트에 있을때는 반드시 식별자값과 같이 있어야한다(식별자 값은 데이터베이스 기본키와 매핑되어있다)
  • 트랜젝션 커밋순간 영속성 컨텍스트에 새로 저장된 엔티티를 데이터베이스에 반영한다(플러시)

 

궁금증) 그럼 여러 엔티티 매니저가 같은 영속성 컨텍스트에 접근 불가능하겟네??

아니다. 접근 가능하다. 이 부분은 나중에 설명하겠다

 

em.persist, em.find

 

EntityManager em = emf.createEntityManger();
EntityTransaction transaction = em.getTransaction();

transaction.begin();

em.persist(memberA);
em.persist(memberB);
em.find(memberC);

transaction.commit();

 

em.persist ->  엔티티를 영속화 시킨다. 다만 영속성컨텍스트에 1차 캐시가 되는 것이지 db에 저장하는 것이 아니다

em.flush -> 영속성 컨텍스트에서 엔티티를 찾고 없으면 db를 조회한다

 

em.detach, em.clear, em.close

 

em.detach -> 특정 엔티티만 준영속 성태로 전환 (해당 엔티티의 쓰기지연 sql저장소까지 제거)

em.clear -> 영속성 컨텍스트를 완전히 초기화 : 해당 영속성 컨텍스트의 모든 엔티티를 준영속 상태로 만듬

em.close -> 영속성 컨텍스트를 종료 : 준영속 상태로 만듬

 

 

em.flush

 

영속성 컨텍스트에 저장된(쓰기지연 저장소) update, insert쿼리 db에 반영

 

영속성 컨텍스트 flush

- em.flush

- 트랜젝션 커밋

- jpql 실행

 

"플러시라는 이름으로 영속성 컨텍스트에 보관된 엔티티를 지우는게 아니라 영속성 컨텍스트의 변경내용을 데이터베이스 동기화 하는 것"

 

 


== 추가적으로 헷갈렸던사항 정리 ==

 

- 준영속 상태는 지연로딩 불가능하다

  -> 프록시 객체를 로딩해두고 실제 사용할때 영속성 컨텍스트를 통해 데이터를 불러오는 방법이다. 준영속 상태는 영속성 컨텍스트가 더는 관리하지 않으므로 지연로딩시 문제가 발생한다.

 

- 플러시가 영속성 컨텍스트를 지우는게 아니다

 

- 트랜젝션 커밋이 영속성 컨텍스트를 지우는게 아니다. entitymanger가 clear,close해야 영속성 컨텍스트가비워진다