JPA

[JPA] 영속성 컨텍스트

뜨는 해 2021. 4. 19. 16:09

영속성 상태

 

JPA는 영속성 컨텍스트는 엔티티(Entity)를 관리한다.

 

이런 엔티티가 뭐냐면 데이터베이스와 1대 1로 매칭되는 일종의 개념이라고 생각해볼 수 있다.

이러한 개념은 객체 지향 프로그래밍의 객체에 매핑이 되게 된다.

 

이러한 엔티티를 관리하는 것이 영속성 컨텍스트인데 엔티티는 이러한 영속성 컨텍스트에 의해 여러 상태를 가질 수 있다.

 


  • New : 엔티티가 새롭게 생성된 상태이다. 이 상태는 영속성 컨텍스트가 이 엔티티를 인지하고 있지 않으므로, 실제 데이터베이스에 반영되지 않는다. 이러한 엔티티를 영속성 컨텍스트에게 관리 받게 하려면 persist() 함수를 통해 엔티티를 관리하도록 만들어야 한다.
  • Managed : 영속성 컨텍스트에 의해 관리되고 있는 엔티티의 상태를 말한다. 이는 곧 엔티티의 정보가 바뀐다면 dirty checking에 의해 변경을 감지하고 데이터베이스에 반영한다.
  • Detached : 영속성 컨텍스트에 관리받던 엔티티가 더 이상 관리 받지 못하고 있는 상태를 말한다. 데이터의 변화가 일어나더라도 데이터베이스 상의 데이터는 변경되지 않는다. 이를 준영속 상태라고 한다.
  • Removed : 엔티티를 삭제한다. 엔티티와 매핑되던 데이터베이스의 데이터 또한 삭제된다.

 

이렇게 총 4가지 상태를 가질 수 있다.

 

이 중에서 가장 세심하게 봐야할 부분은 Managed 상태일 것 같다.

 

 

JPA 캐시


JPA는 다른 데이터베이스 관리 API 에 비해서 성능상의 이점을 가질 수 있다.

이는 영속성 컨텍스트에서 관리하는 캐시 덕분이다.

 

 

만약 내가 member 엔티티를 만들어 persist()를 수행한다면 이 member 엔티티는 영속성 컨텍스트에서 관리하게 된다.

여기에서 가장 중요한 부분은 "데이터베이스에 바로 반영이 되지 않는다"는 것이다.

 

처음 엔티티가 영속상태가 된다면 캐시에서 관리 받게 된다.

 

이렇게 관리를 받는 엔티티가 데이터베이스에 들어가는 경우는 직접 flush()를 해주거나, 조회 등의 행위를 했을 경우 데이터베이스에 반영이 되게 된다.

 

그렇다면 수정이 이루어질 경우 어떻게 바뀐 것을 인지하는 것일까?

 

사실 영속성 컨텍스트는 최초로 등록된 엔티티의 스냅샷을 가지고 있다.

엔티티의 데이터가 바뀔 경우 스냅샷에 의해 체킹이 되고, 만약 다를 경우 업데이트 쿼리를 날리게 된다.

 

위 사진에 쓰기 지연 SQL 저장소가 있는데 이는 실질적으로 바뀌어지는 쿼리를 모아놨다가 데이터베이스에 한번에 flush하기 위해서 만들어졌다.

 

이런 특성 때문에 한가지 이점을 얻을 수 있는데, 예를 들면

 


member.updateName("홍길동");

member.updateName("자식");

member.updateName("John");

member.updateName("홍길동");

 

이렇게 엔티티의 변화가 나타났다고 하자.

여러번 이름이 바뀌었지만 최종적으로 처음과 다름이 없다.

 

영속성 컨텍스트는 이러한 변화를 감지하고, 처음 상태와 다름 없을 경우 업데이트 쿼리를 날리지 않는다.

 

그렇기 때문에 특정 상황에서 성능적인 우위를 점할 수 있다.

 


오역, 틀린 부분 지적은 댓글로 남겨주시면 반영하겠습니다!