[CS] 영속성 컨텍스트

박상민·2023년 6월 15일
0

Computer Science

목록 보기
22/29

❗️영속성 컨텍스트란?

Server Side와 Database 사이에 엔티티를 저장하는 논리적인 영역이다. 엔티티 매니저로 엔티티를 저장하거나 조회하면 엔티티 매니저는 영속성 컨텍스트에 엔티티를 보관하고 관리한다.
영속성 컨텍스트는 엔티티 매니저를 생성할 때 하나 만들어진다. 그리고 엔티티 매니저를 통해서 영속성 컨텍스트에 접근할 수 있고, 관리할 수 있다.

💡 엔티티의 생명주기

✔️ 비영속 상태

객체를 생성만 하여 영속성 컨텍스트와 관계가 없는 상태

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

✔️ 영속 상태

객체를 생성 후 영속성 컨텍스트에 저장한 상태

// 객체를 생성한 상태 (비영속)
Member member = new Member();
member.setId("member1");
member.setUsername("회원1");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
// 객체를 저장한 상태 (영속)
em.persist(member);

✔️ 준영속 상태

영속성 컨텍스트에 저장되었다가 분리된 상태

// 회원 엔티티를 영속성 컨텍스트에서 분리, 준영속 상태
em.detach(member);

✔️ 삭제 상태

삭제된 상태

// 객체를 삭제한 상태 (삭제)
em.remove(member);

❗️영속성 컨텍스트의 특징

1. 영속성 컨텍스트와 식별자 값

💡 @id 값으로 구분하기 때문에 @id 가 없는 엔티티는 JPA에서 사용할 수 없다.

엔티티를 식별자 값(엔티티의 @id로 테이블의 기본키와 매핑한 값)으로 구분

2. 영속성 컨텍스트와 데이터베이스 저장

JPA는 보통 트랜잭션을 커밋하는 순간 영속성 컨텍스트에 새로 저장된 엔티티를 데이터베이스에 반영하게 되고 이 과정을 flush라고 한다.

3. 영속성 컨텍스트가 엔티티를 관리하는 것의 장점

  • 동일성 보장
    @id를 식별자로 사용하기 때문에 동일성을 보장한다.
  • 트랜잭션을 지원하는 쓰기 지연
    1. 회원 A 영속
    2. 회원 B 영속
    3. 트랜잭션이 끝나고 트랜잭션 커밋이 진행된다. 이후 쓰기 지연 된 SQL들을 한번에 Flush한다. 이후 데이터베이스 동기화가 진행되고, 실제 데이터베이스의 커밋을 진행한다.
  • 변경 감지
    영속성 컨텍스트를 사용하기 때문에 JPA는 엔티티를 수정할 때 단순히 엔티티를 조회하여 데이터만 변경하면 된다. 변경 감지 기능을 이용해서 데이터베이스에 자동 반영된다.
  • 지연 로딩
    실제 데이터가 필요한 순간에서야 데이터베이스를 조회하여 프록시 객체를 초기화한다. 만약 영속성 컨텍스트에 객체가 이미 존재한다면 프록시 객체가 아닌 실제 객체를 사용한다.
  • 1차 캐시

❗️1차 캐시 & 2차 캐시

1. 1차 캐시

영속성 내부에는 1차 캐시가 존재한다. 영속 상태의 엔티티를 이곳에서 저장하기 때문에 만약 엔티티를 조회했을 때 1차 캐시에 엔티티가 존재한다면 DB를 찾아보지 않는다. 캐시로써의 기능과 장점을 가지고 있다.

최초에 데이터에 접근할 때만 데이터베이스를 조회하여 데이터를 가져오고, 이후부터는 1차 캐시를 이용해 데이터를 반환한다. 그렇기 떄문에 반복 가능한 읽기 등급의 트랜잭션 격리 수준을 데이터베이스가 아닌 애플리케이션 차원에서 제공할 수 있다.

하지만 엔티티 매니저는 트랜잭션 단위로 만들고 해당 데이터베이스 트랜잭션이 끝날 때 같이 종료되기 때문에 1차 캐시 또한 소멸된다. 비즈니스 로직이 복잡할 경우에만 성능상 이득이 있다.

2. 2차 캐시

애플리케이션 수준에서 공유하는 캐시이며 JPA에서는 공유 캐시라고도 한다. 2차 캐시는 애플리케이션을 종료할 때까지 유지된다. 2차 캐시를 적용 시, 엔티티 매니저를 통해 데이터를 조회할 때 우선 2차 캐시에서 찾고 없으면 데이터베이스를 조회한다. 이 때 2차 캐시는 동시성을 극대화하기 위해 캐시 한 객체를 직접 반환하지 않고 복사본을 만들어 반환한다. 캐시한 객체를 바로 반환하면 여러 곳에서 같은 객체를 동시에 수정하는 문제가 발생할 수 있기 때문에 복사하여 전달한다. 2차 캐시까지 사용하게 되면 애플리케이션 범위의 캐시이므로 데이터베이스 조회가 1차 캐시만 사용할 때 보다 획기적으로 줄어든다.

profile
💡 클린코드를 지향하는 Backend Developer

0개의 댓글