TIL - [DAY 4] 영속성 컨텍스트

jihan kong·2022년 5월 17일
0

Spring Boot 개념정리

목록 보기
4/6
post-thumbnail

JPA의 특징에 대해서 계속해서 공부하고 있다. JPA의 또 다른 특징 중 하나는 영속성 컨텍스트를 가지고 있다는 것이다.

1. JPA의 영속성 컨텍스트

영속성이라는 것은 데이터를 영구적으로 저장하는 것이라는 내용을 강의 서두에서 JPA의 Definition에 관해서 공부할 때 배웠다. (https://velog.io/@kjh950330/TIL-DAY-2-JPA%EB%9E%80)

그렇다면 컨텍스트(context) 란 무엇일까?

컨텍스트의 쉬운 이해를 위해 다음 철수와 영희, 길동이와 영희의 관계를 살펴보자.

철수가 영희의 컨텍스트를 안다는 것은 영희의 일거수일투족을 모두 안다는 것이다.

그러나, 위 그림에서 유추할 수 있듯이 철수와 다르게 영희는 철수를 별로 좋아하지 않는 것 같다...😥😥

길동이와 영희는 서로의 컨텍스트를 가지고 있고.. 다행히 서로 좋아하는 것 같다.

이처럼, 컨텍스트는 한 마디로 대상에 대한 모든 정보를 가지고 있는 것을 의미한다. 이 용어 자체는 앱이나 웹, 정보통신 등 정말 다양한 곳에서 다양하게 쓰이기 때문에 개념이 약간 모호할 수 있다.

컨텍스트에 대해 더욱 알고 싶어 구글링을 해보았는데, context는 어떤 행위 (Task, Method)가 일어나기 위한 정보의 통칭이라고 한다.
(https://pflb.tistory.com/30 Path7inder님의 블로그 참조)

여튼 컨텍스트의 개념은 이정도로 정리하면 될 것 같다.

2. 컨텍스트의 작동원리

컨텍스트는 object 사이에서 다음과 같이 작동한다. Java 프로그램에서 '동물' 데이터를 생성했다고 가정하자.

데이터를 생성하면 DB에 바로 저장되는 것이 아니라 영속성 컨텍스트에 먼저 저장이 되고, 이를 DB에 전송하여 DB에 저장하는 방식으로 매커니즘이 동작하게 된다.

만약 JAVA 프로그램에서 동물 데이터(객체)를 삭제하면 어떻게 될까?

"영속성 컨텍스트의 동물 Data" 와 "DB의 동물 Data" 모두 삭제가 된다. 이른바, "동기화"가 된것이다.

이처럼 중간 매개체 역할로 영속성 컨텍스트가 작동하고 있다.

3. 엔티티 생명 주기

이처럼 영속성 컨텍스트(Persistence Context) 에 대해서 알게되었다. 그렇다면 지난번 JPA의 정의에 대해서 학습할 때 알게된 엔티티(Entity)를 영구 저장할 때도 영속성 컨텍스트에 저장하는 것일까?

답은 YES다. 엔티티를 영구 저장하는 환경으로 엔티티 매니저를 통해 영속성 컨텍스트에 접근하게 된다.

엔티티의 생명주기의 세부 내용은 다음과 같다.

설명으로는 어려울 수 있으니 직접 코드를 살펴보자.

영속성 컨텍스트에 저장 후 DB에 반영하는 예시 코드

Item item = new Item();				// 1. 
item.setItemNm("테스트 상품");

EntityManager em = entityManagerFactory.createEntityManager();		// 2.

EntityTransaction transaction = em.getTransaction();  // 3.
transaction.begin();

em.persist(item);		// 4.

transaction.commit();	// 5.

em.close();				// 6.

<코드 설명>
  1. 영속성 컨텍스트에 저장할 상품 엔티티를 하나 생성. new 키워드를 통해 생성했으므로 영속성 컨텍스트와 관련이 없는 상태
  2. 엔티티 매니저 팩토리로부터 엔티티 매니저 생성
  3. 엔티티 매니저는 데이터 변경 시 데이터의 무결성을 위해 반드시 트랜잭션을 시작해야함. 여기서의 트랜잭션도 데이터베이스의 트랜잭션과 같은 의미.
  4. 생성한 상품(item) 엔티티가 영속성 컨텍스트에 저장된 상태. 아직 DB에 INSERT 하지는 않은 상태
  5. 트랜잭션을 데이터베이스 반영. 이 때, 영속성 컨텍스트에 저장된 상품 정보가 데이터베이스에 INSERT 되면서 반영됨.
  6. 엔티티 매니저와 엔티티 매니저 팩토리의 close() 메소드를 호출해 사용한 자원을 반환함.

4. 영속성 컨텍스트 사용 시 이점

JPA는 애플리케이션과 데이터베이스 사이에 영속성 컨텍스트라는 중간 계층을 만듦으로써 버퍼링, 캐싱 등을 할 수 있는 장점을 가지게 되었다.

1. 1차 캐시

영속성 컨텍스트에는 1차 캐시가 존재하며 Map<KEY, VALUE> 로 저장된다. entityManager.find() 메소드 호출 시 영속성 컨텍스트의 1차 캐시를 조회하게 된다. 엔티티가 존재하면 해당 엔티티를 반환하고, 엔티티가 없으면 데이터베이스에서 조회 후 1차 캐시에 저장 및 반환한다.

2. 동일성 보장

하나의 트랜잭션에서 같은 키값으로 영속성 컨텍스트에 저장된 엔티티 조회 시 같은 엔티티 조회를 보장한다. 바로 1차 캐시에 저장된 엔티티를 조회하기 때문에 가능한 것이다.

3. 트랜잭션을 지원하는 쓰기 지연

영속성 컨텍스트에는 쓰기 지연 SQL 저장소가 존재한다. entityManager.persist() 를 호출하면 1차 캐시에 저장되는 것과 동시에 쓰기 지연 SQL 저장소 에 SQL문이 저장된다. 이렇듯, SQL을 쌓아두고 트랜잭션을 커밋하는 시점에 저장된 SQL 문들이 flush 되면서 데이터베이스에 반영되기 때문에 성능면에서 이점을 볼 수 있다.

4. 변경 감지

JPA는 1차 캐시에 데이터베이스에서 처음 불러온 엔티티의 스냅샷을 가지고 있는 셈이다. 그리고 1차 캐시에 저장된 엔티티와 스냅샷을 비교한 후, 변경된 내용이 있다면 UPDATE SQL 문을 쓰기 지연 SQL 저장소 에 담아둔다. 그리고 데이터베이스 커밋 시점에 변경 내용을 자동으로 반영한다. 즉, 따로 update문을 호출할 필요가 없게 되는 것이다. 이를 더티체킹(dirty checking)이라고 한다.


결론적으로 자바와 DB는 항상 영속성 컨텍스트를 통해 상호작용하며 데이터를 전달 혹은 생성, 변경하고 저장하게 되는 것이다.

profile
학습하며 도전하는 것을 즐기는 개발자

0개의 댓글