본문 바로가기
Framework/🍃Spring

JPA - 영속성 컨텍스트란?

by 발개발자 2022. 11. 25.
반응형

JPA를 이해하는데 가장 중요한 용어인 영속성 컨텍스트에 대해 알아보자.

 

영속성컨텍스트란 엔티티를 영구 저장하는 환경

 

 

그렇다. 영속성 컨텍스트는 DB가 아닌, JPA의 EntityManager가 엔티티를 관리하는 형태이다.

 

여기서 영속성 컨텍스트에 저장하기 위해 비영속 상태의 객체를 만들어서 영속성 컨텍스트에 저장해보자!

 

먼저, 비영속상태란 엔티티객체를 생성하고 EntityManager에게 위임시켜놓지 않은 상태이다.

// 비영속상태의 객체
Member member = new Member();
member.setId("member1");
member.setUsername("회원1");

 

여기서 EntityManager의 persist를 통해 영속성 컨텍스트에 저장할 수 있다.

 

EntityManager em = emf.createEntityManager();
em.getTransaction().begin();

// 객체를 저장한 상태(영속)
em.persist(member);

 

즉, persist를 통해 DB에 바로 쿼리를 날리는게 아니라, 영속상태로 저장해놓고 트랜잭션을 커밋하는 시점에 영속성 컨텍스트에 있던 녀석들이 DB에 쿼리로 날라가는 것이다.

 

그런 이러한 영속성 컨텍스트를 왜 사용할까?

영속성 컨텍스트의 이점을 알아보자.

 

  1차 캐시

JPA로 조회시 영속성 컨텍스트의 1차 캐시에서 먼저 조회한다.

만약 해당 객체가 없으면 DB에서 불러와서 1차 캐시에 저장해놓고 트랜잭션 단위로 DB에 접근안하고 1차 캐시에서 정보를 불러온다.

근데 실제 어플리케이션들은 서비스 단위에서 트랜잭션이 일어나기 때문에, 1차 캐시로 인해 성능이 유의미하게 향상되거나 이런건 없다고 한다.

 

만일, 하나의 트랜잭션 안에서 다중 insert 작업이 일어나면 영속성 컨텍스트의 쓰기 지연 SQL 저장소에서 SQL을 저장하고 1차 캐시에 insert 캨체들을 저장해 놓게 된다. 그리고 트랜잭션이 커밋되는 시점에 DB에 SQL을 날린다.

 

 

 

  동일성 보장

Member a = em.find(Member.class, "member1");
Member b = em.find(Member.class, "member1");

System.out.println(a == b); // 동일성 비교 true

 

JPA가 영속성 컨텍스트에 속한 엔티티의 동일성을 보장해준다.

마치 자바 Colletion에서 꺼내서 똑같은 레퍼런스면 동일성을 보장하는 것 처럼 말이다.

이게 가능한 이유는 1차캐시에 이미 객체를 저장해놨기 때문이다.

단, 당연히 같은 트랜잭션에서만 동일성을 보장한다.

 

 

  변경 감지 (Dirty Checking)

Member.setUsername("변경");

JPA에서 Set만으로 Update쿼리가 가능한 이유가 바로 스냅샷이라는 기능이 있기때문이다.

최초에 영속 컨텍스트에 저장될 때 객체를 스냅샷을 찍어놓고 flush(commit)시점에서 1차캐시의 Entity와 스냅샷의 Entity와 비교해서 만약 다르면 update 쿼리를 생성해서 날려준다.

 

 

 

 

본 내용은 아래의 강의를 참고했습니다.

https://www.inflearn.com/course/ORM-JPA-Basic

반응형

댓글