영속성 컨텍스트

  • Persistence를 한글로 번역하면 영속성, 지속성 이라는 뜻
  • Persistence를 객체의 관점으로 해석해 보자면 객체가 생명(객체가 유지되는 시간)이나 공간(객체의 위치)을 자유롭게 유지하고 이동할수 있는 객체의 성질’을 의미
  • Entity 객체를 효율적으로 쉽게 관리하기 위해 만들어진 공간
  • 개발자들이 직접 SQL을 작성하지 않아도 JPA를 사용하여 DB에 데이터를 저장하거나 조회할 수 있으며 수정, 삭제 가능

  • 이러한 일련의 과정을 효율적으로 처리하기 위해 JPA는 영속성 컨텍스트에 Entity 객체들을 저장하여 관리하면서 DB와 소통

영속성 컨텍스트의 기능

1차 캐시

  • 영속성 컨텍스트는 내부적으로 캐시 저장소를 가지고 있음
    • 저장하는 Entity 객체들이 1차 캐시 즉, 캐시 저장소에 저장된다고 생각하면 됨
    • 캐시 저장소는 Map 자료구조 형태로 되어있음
      • key에는 @Id로 매핑한 기본 키 즉, 식별자 값을 저장
      • value에는 해당 Entity 클래스의 객체를 저장
      • 영속성 컨텍스트는 캐시 저장소 Key에 저장한 식별자값을 사용하여 Entity 객체를 구분하고 관리함

Entity 저장

  • em.persist(memo); 메서드가 호출되면 memo Entity 객체를 캐시 저장소에 저장

Entity 조회

  1. 캐시 저장소에 조회하는 Id가 존재하지 않은 경우
  • 캐시 저장소 조회

  • DB SELECT 조회 후 캐시 저장소에 저장 
  • em.find(Memo.class, 1); 호출 시 캐시 저장소를 확인 한 후 해당 값이 없다면 DB에 SELECT 조회 후 해당 값을 캐시 저장소에 저장하고 반환
  • DB에서 데이터를 조회만 하는 경우에는 데이터의 변경이 발생하는 것이 아니기 때문에 트랜잭션이 없어도 조회가 가능

2. 캐시 저장소에 조회하는 Id가 존재하는 경우

  • em.find(Memo.class, 1); 호출 시 캐시 저장소에 식별자 값이 1이면서 Memo Entity 타입인 값이 있는지 조회
    • 값이 있다면 해당 Entity 객체를 반환

'1차 캐시' 사용의 장점

  1. DB 조회 횟수를 줄임
  2. **'1차 캐시'**를 사용해 DB row 1개 당 객체 1개가 사용되는 것을 보장 (객체 동일성 보장)

Entity 삭제

  1. 삭제할 Entity를 조회한 후 캐시 저장소에 없다면 DB에 조회해서 저장

2. em.remove(entity);

  • em.remove(memo); 호출 시 삭제할 Entity를 DELETED 상태로 만든 후 트랜잭션 commit 후 Delete SQL이 DB에 요청

쓰기 지연 저장소(ActionQueue)

flush()

  • flush 메서드는 영속성 컨텍스트의 변경 내용들을 DB에 반영하는 역할을 수행
    • 쓰기 지연 저장소의 SQL들을 DB에 요청하는 역할을 수행
  • 트랜잭션을 설정하지 않고 플러시 메서드를 호출하면 no transaction is in progress 메시지와 함께 TransactionRequiredException 오류가 발생

변경 감지(Dirty Checking)

- 영속성 컨텍스트에 저장된 Entity가 변경될 때마다 Update SQL이 쓰기 지연 저장소에 저장된다면 하나의 Update SQL로 처리할 수 있는 상황을 여러번 Update SQL을 요청하게 되기 때문에 비효율적이게 됨

JPA에서는 Update를 처리하는 방법

  • JPA는 영속성 컨텍스트에 Entity를 저장할 때 최초 상태(LoadedState)를 저장
    • 트랜잭션이 commit되고 em.flush(); 가 호출되면 Entity의 현재 상태와 저장한 최초 상태를 비교
    • 변경 내용이 있다면 Update SQL을 생성하여 쓰기 지연 저장소에 저장하고 모든 쓰기지연 저장소의 SQL을 DB에 요청
    • 마지막으로 DB의 트랜잭션이 commit 되면서 반영됨
  • 따라서 변경하고 싶은 데이터가 있다면 먼저 데이터를 조회하고 해당 Entity 객체의 데이터를 변경하면 자동으로 Update SQL이 생성되고 DB에 반영됨
    • 이러한 과정을 변경 감지, Dirty Checking이라고 함

EntityManager 

  • 영속성 컨텍스트에 접근하여 Entity 객체들을 조작하기 위해서는 EntityManager가 필요
    • EntityManager는 이름 그대로 Entity를 관리하는 관리자
  • 개발자들은 EntityManager를 사용해서 Entity를 저장하고 조회하고 수정하고 삭제할 수 있음
  • EntityManager는 EntityManagerFactory를 통해 생성하여 사용 가능

EntityManagerFactory

  • EntityManagerFactory는 일반적으로 DB 하나에 하나만 생성되어 애플리케이션이 동작하는 동안 사용됨
    • EntityManagerFactory를 만들기 위해서는 DB에 대한 정보를 전달해야 함

트랜잭션

  • DB 데이터들의 무결성과 정합성을 유지하기 위한 하나의 논리적 개념
    • DB의 데이터들을 안전하게 관리하기 위해서 생겨난 개념
  • 가장 큰 특징은 여러 개의 SQL이 하나의 트랜잭션에 포함될 수 있다는 점
    • 이때, 모든 SQL이 성공적으로 수행이 되면 DB에 영구적으로 변경을 반영하지만 SQL 중 단 하나라도 실패한다면 모든 변경을 되돌림
  • JPA는 DB의 이러한 트랜잭션 개념을 사용하여 효율적으로 Entity를 관리함

JPA의 트랜잭션

  • 영속성 컨텍스트에 Entity 객체들을 저장했다고 해서 DB에 바로 반영 되지는 않음

  • DB에서 하나의 트랜잭션에 여러 개의 SQL을 포함하고 있다가 마지막에 영구적으로 변경을 반영하는 것 처럼 JPA에서도 영속성 컨텍스트로 관리하고 있는 변경이 발생한 객체들의 정보를 쓰기 지연 저장소에 전부 가지고 있다가 마지막에 SQL을 한번에 DB에 요청해 변경을 반영함
  • JPA에서 이러한 트랜잭션의 개념을 적용하기 위해서는 EntityManager에서 EntityTransaction을 가져와 트랜잭션을 적용할 수 있습니다.
    • EntityTransaction et = em.getTransaction();
    • 해당 코드를 호출하여 EntityTransaction을 가져와 트랜잭션을 관리할 수 있음
  • et.begin();
    • 트랜잭션을 시작하는 명령어
  • et.commit();
    • 트랜잭션의 작업들을 영구적으로 DB에 반영하는 명령어
  • et.rollback();
    • 오류가 발생했을 때 트랜잭션의 작업을 모두 취소하고, 이전 상태로 되돌리는 명령어

Spring의 트랜잭션

  • @Transactional 애너테이션을 클래스나 메서드에 추가하면 쉽게 트랜잭션 개념을 적용할 수 있음
    • 메서드가 호출되면, 해당 메서드 내에서 수행되는 모든 DB 연산 내용은 하나의 트랜잭션으로 묶임
    • 이때, 해당 메서드가 정상적으로 수행되면 트랜잭션을 커밋하고, 예외가 발생하면 롤백함
    • 클래스에 선언한 @Transactional은 해당 클래스 내부의 모든 메서드에 트랜잭션 기능을 부여함
    • 이때, save 메서드는 @Transactional 애너테이션이 추가되어있기 때문에 readOnly = true 옵션인 @Transactional을 덮어쓰게 되어 readOnly = false 옵션으로 적용됨
      • readOnly = true 옵션
        • 트랜잭션에서 데이터를 읽기만 할 때 사용됨
        • 이 속성을 사용하면 읽기 작업에 대한 최적화를 수행할 수 있음
        • 만약, 해당 트랜잭션에서 데이터를 수정하려고 하면 예외가 발생하기 때문에 주의해야함

영속성 컨텍스트와 트랜잭션의 생명주기

  • 스프링 컨테이너 환경에서는 영속성 컨텍스트와 트랜잭션의 생명주기가 일치함
  • 트랜잭션이 유지되는 동안은 영속성 컨텍스트도 계속 유지가 되기 때문에 영속성 컨텍스트의 기능을 사용할 수 있음

'🗂️ Study > 🌿Spring' 카테고리의 다른 글

인증(Authentication) & 인가(Authorization)  (0) 2024.05.28
Query Methods  (0) 2024.05.21
Entity  (0) 2024.05.21
JPA  (0) 2024.05.21
IoC Container & Bean  (0) 2024.05.21