영속성 컨텍스트

구동희·2022년 8월 28일
0
post-thumbnail

영속성 컨텍스트란?

엔티티(Entity)를 저장하고 관리하는 저장소이다.
JPA는 메서드를 호출하면 DB에서 바로 작업을 처리하지 않고 영속성 컨텍스트를 거친 후, 작업을 처리한다.

그렇다면 영속성 컨텍스트를 사용하는 이유는 무엇일까?

영속성 컨텍스트를 사용하는 이유

JPA가 영속성 컨텍스트를 사용하는 이유는 아래와 같다.

  • 일차 캐시
  • 동일성 보장
  • 쓰기 지연
  • 변경 감지

하나씩 살펴보자.

1차 캐시

영속성 컨텍스트는 내부적으로 1차 캐시라는 공간을 가지고 Entity들을 저장한다.
JPA는 persist()를 한다고 해서 DB에 insert문이 날아가는게 아닌 영속성 컨텍스트의 1차 캐시 공간에 저장한다.

이렇게 함으로써 약간의 성능상 이점을 가지고 올 수 있다.
만약 User에 대한 삽입과 조회가 하나의 트랜잭션에서 일어난다면 조회시 DB에 접근할 필요가 없기 때문에 성능상의 이점을 가지고 올 수 있다.
왜냐하면 persist()를 통해 영속성 컨텍스트에 저장된 User를 가지고 오면 되기 때문이다.

동일성 보장

JAVA에서는 같은 주소 값을 가진 객체 두개를 동일한 객체로 판단한다.
하지만 DB에서 같은 필드를 가진 객체를 따로 두번 조회 한다면 두 객체는 다른 객체이다.
같은 필드를 가졌지만 각각 따로 생성된 객체이기 때문이다.

그래서 패러다임의 일치를 위해 JPA는 영속성 컨텍스트의 1차캐시를 통해 동일성을 보장한다.

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

System.out.println(a == b); // true

위와 같이 JPA는 하나의 트랜잭션 단위에서 같은 Id를 가진 객체를 조회하면 동일성을 보장해준다.


왜냐하면 User aUser b 모두 1차캐시에 있는 같은 user를 가리키기 때문이다.
위와 같이 JPA는 엔티티의 동일성을 보장한다.

쓰기 지연

영속성 컨텍스트를 사용함으로써 엔티티를 buffer에 모아서 DB에 한번에 저장할 수 있다.
이를 통해 약간의 성능적 이점을 가지고 올 수 있다. 매번 DB에 접근하여 데이터를 저장하지 않고 한번에 저장하기 때문이다.

이러한 buffer 기능을 제공 할 수 있는 이유는 다음과 같다.

JPA의 영속성 컨텍스트는 Entity를 1차 캐시에 저장할 때, 쓰기 지연 SQL 저장소라는 곳에 관련된 SQL문도 함께 저장한다.
그리고 트랜잭션이 커밋되는 시점에서 SQL 저장소에 있는 쿼리문들을 DB에 반영한다.

이러한 구조 덕분에 JPA는 쓰기 지연이 가능하다.

변경 감지

JPA는 update()와 같은 메서드를 호출하지 않아도 Entity의 변경사항을 감지하고 반영한다.

	User user = em.find(User.class, 1l)
    user.setName("updatedName");
    
    // em.update(user) => JPA는 이러한 메서드가 없음

위와 같이 Entity의 필드를 변경한다면 이를 JPA가 감지하고 최종적으로는 DB에 적용한다.
이를 통해 실제 객체의 데이터를 변경 하듯이 DB의 데이터를 변경 할 수 있다.

이렇게 JPA가 변경을 자동으로 감지하고 적용할 수 있는 이유는 다음과 같다.

영속성 컨텍스트의 1차 캐시는 사실 스냅샷을 추가로 가지고 있다.
그리고 Entity가 최초로 영속성 컨텍스트에 등록될 때 Entity에 대해서 스냅샷을 저장한다.

	User user = em.find(User.class, 1l)
    user.setName("updatedName");

이후에, user.setName("updatedName");과 같이 Entity의 상태가 변경되면 1차 캐시의 Entity스냅샷이 불일치 하게 된다.

트랜잭션이 커밋되는 시점(정확히는 em.flush()되는 시점)에 불일치를 비교하고 Update쿼리를 생성한 후 DB에 반영한다.

💡 Flush
Flush란 영속성 컨텍스트의 변경내용을 데이터베이스에 반영하는 것이다.

마치면서

이상으로 JPA의 영속성 컨텍스트를 사용함으로써 가져오는 이점들을 살펴보았다. 영속성 컨텍스트는 JPA의 중요한 개념이기 때문에, 영속성 컨텍스트에 대한 이해에 도움이 되었으면 좋겠다.

profile
천천히 배워가는 개발꿈나무

0개의 댓글