UL :)
UL의 개발 블로그
UL :)
전체 방문자
오늘
어제
  • 분류 전체보기 (220)
    • 일상 (1)
    • 회고록 (7)
    • ChatGPT 아카이빙 (0)
    • PS(Java) (114)
      • 백준 (37)
      • 인프런 강의 문제 (77)
    • Web (69)
      • Spring (18)
      • JPA (7)
      • JSP (9)
      • HTML5 (12)
      • CSS (19)
      • HTTP (0)
      • 보안 (2)
    • Language (5)
      • Java (3)
      • JS (1)
      • Python (1)
    • Git, GitHub (4)
    • Settings (18)
      • IntelliJ (7)
      • Eclipse (2)
      • VSCode (3)
      • Android Studio (1)
      • VMware (2)
      • Mac (0)
    • Etc (1)

블로그 메뉴

  • 홈
  • 태그

공지사항

인기 글

태그

  • ORM
  • argumentresolver
  • consumes
  • HttpMessageConverter
  • TABLE 전략
  • 동일성보장
  • 영속성
  • IDENTITY 전략
  • EntityManagerFactory
  • SEQUENCE 전략
  • @ManyToOne
  • ViewName반환
  • @RequestParam
  • 백준
  • @GetMapping
  • 엔티티 매핑
  • BOJ
  • JPA
  • 영속성컨텍스트
  • ReturnValueHandler
  • produces
  • 요청헤더
  • @Table
  • 정렬
  • 1차 캐시
  • @JoinColumn
  • HandlerMethodArgumentResolver
  • @Column
  • @PostMapping
  • @Id

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
UL :)

UL의 개발 블로그

[Inflearn] JPA - 영속성관리
Web/JPA

[Inflearn] JPA - 영속성관리

2022. 3. 22. 14:46

김영한 강사님의 '자바 ORM 표준 JPA 프로그래밍-기본편' 강의 정리

2022.03.17~ 03.31 진행

강의를 듣고 개인적으로 정리한 글입니다. 코드와 그림 출처는 김영한 강사님께 있습니다. 문제 있을 시 알려주세요.

 

영속성 컨텍스트

JPA는 영속성 컨텍스트에 엔티티를 저장한다. 영속성 컨텍스트는 "엔티티를 영구 저장하는 환경" 이라는 뜻이다. 영속성 컨텍스트는 논리적인 개념이며 눈에 보이지 않는다.

영속성 컨텍스트 접근하기

  • 엔티티 매니저를 통해서 영속성 컨텍스트에 접근한다.
  • EntityManager.persist(entity);를 하면 엔티티를 영속화한다. (DB에 저장하는게 아님, 영속성 컨텍스트에 저장)

 

엔티티 매니저 팩토리와 엔티티 매니저

EntityManagerFactory를 통해서 고객의 요청이 올때마다 EntityManager를 생성한다.

EntityManager는 내부적으로 DB 커넥션을 통해 DB를 사용한다.

EntityManager를 생성하면 1대1로 영속성 컨텍스트가 생성되며 이렇게 1:1인 관계를 J2SE 환경이라고 한다.

J2EE, 스프링 프레임워크 같은 컨테이너 환경: 엔티티 매니저와 영속성 컨텍스트가 N:1

 

엔티티의 생명주기

  • 비영속 (new/transient) : 객체만 생성한 상태로, 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
  • 영속 (managed) : 영속성 컨텍스트에 관리되는 상태
    • EntityManager.persist(객체); 객체를 저장한 상태.
  • 준영속 (detached) : 영속성 컨텍스트에 저장되었다가 분리된 상태
    • EntityManager.detach(객체);
  • 삭제 (removed) : 삭제된 상태
    • EntityManager.remove(객체); 객체를 삭제한 상태 → 커밋되면 DB에서 삭제됨

엔티티 조회 - 1차 캐시

애플리케이션에서 엔티티를 조회할 때, 다음 과정을 거친다.

  1. 1차 캐시에 있는지 확인
  2. 1차 캐시에 없으면 DB를 조회해서 가져온다
  3. 1차 캐시에 저장한 후
  4. 객체를 반환

※ 1차 캐시의 유지 기간 : 고객의 요청(트랜잭션 단위)이 시작하고 끝날 때

=> 1차 캐시는 트랜잭션 단위로 유지되므로 성능 상 이점이 크지는 않지만, 영속 엔티티의 동일성을 보장해준다.

1차 캐시로 반복 가능한 읽기(REPEATABLE READ) 등급의 트랜잭션 격리 수준을 데이터베이스가 아닌 애플리케이션 차원에서 제공.

 

엔티티 등록 - 트랜잭션을 지원하는 쓰기 지연

  • EntityManger.persist(객체); 를 하면 객체들이 영속성 컨텍스트에 저장된다(=1차 캐시에 저장된다)
  • transaction.commit(); 이 실행되는 시점에 쓰기 지연 SQL 저장소에서 쌓인 쿼리들이 DB에 flush 되면서 최종 commit 된다.

=> 최적화 가능 : hibernate.jdbc.batch.size 옵션으로 DB에 한번에 여러 쿼리를 모아서 보낼 수 있는 등, 성능이 좋아 질 수 있다.

EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();

//데이터 변경시 트랜잭션을 시작해야함
transaction.begin(); // [트랜잭션] 시작
em.persist(memberA);
em.persist(memberB);

transaction.commit(); // [트랜잭션] 커밋 --SQL--> DB

 

엔티티 수정 - 변경 감지(Dirty Checking)

JPA는 변경 감지(Dirty Checking) 기능을 제공한다. App에서 엔티티를 수정하기만 해도 변경이 감지되어 DB에 반영을 해준다. 따라서 우리는 할 일이 없다!

  1. flush()
  2. 1차캐시와 스냅샷(최초로 영속성 컨텍스트에 저장된 시점)을 비교
  3. 변경사항이 있으면 SQL 저장소에 update 쿼리를 생성
  4. EntityTransaction.commit() → flush → DB commit

 

Flush

flush는 영속성 컨텍스트의 변경내용을 데이터베이스에 반영하는 작업이다.

flush를 하면 다음 과정을 거친다.

  1. 변경 감지
  2. 수정된 엔티티를 쓰기 지연 SQL 저장소에 등록
  3. 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송(등록, 수정, 삭제 쿼리)
  4. 즉 영속성 컨텍스트의 변경내용을 데이터베이스에 동기화한다.

 

※ 주의 : flush가 영속성 컨텍스트를 비우지는 않음. DB에 내보낼 뿐

   트랜잭션이라는 작업 단위가 중요 → 커밋 직전에만 동기화하면 된다(??)

 

영속성 컨텍스트를 flush하기

  • em.flush() - 직접 호출
  • 트랜잭션 커밋을 하거나, JPQL 쿼리 실행을 하면 자동 플러시된다.

JPQL 쿼리 실행시 플러시가 자동으로 호출되는 이유?
JPQL에서 사용할 객체가 실제 DB에 저장되어 있지 않으면 곤란한 상황들이 있을 수 있기 때문

 

준영속 상태

영속 상태의 엔티티가 영속성 컨텍스트에서 분리(detached)된 상태를 준영속 상태라고 한다.
준영속 상태에서는 영속성 컨텍스트가 제공하는 기능을 사용하지 못한다.

준영속 상태로 만들기

  • em.detach(entity) : 특정 엔티티를 준영속 상태로 전환
  • em.clear() : 영속성 컨텍스트 초기화
  • em.close() : 영속성 컨텍스트 종료

 

영속성 컨텍스트의 이점 정리

  • 1차 캐시
  • 동일성(identity) 보장
  • 트랜잭션을 지원하는 쓰기 지연 (transactional write-behind)
  • 변경 감지(Dirty Checking)
  • 지연 로딩(Lazy Loading)

 

저작자표시 비영리 변경금지 (새창열림)

'Web > JPA' 카테고리의 다른 글

[Inflearn] JPA - 값 타입(작성전)  (0) 2022.05.11
[Inflearn] JPA - 객체지향 쿼리 언어  (0) 2022.03.31
[Inflearn] JPA - 엔티티매핑  (0) 2022.03.22
[Inflearn] JPA 시작하기 + JPQL이란?  (0) 2022.03.21
[Inflearn] ORM, JPA란 무엇인가  (0) 2022.03.21
    'Web/JPA' 카테고리의 다른 글
    • [Inflearn] JPA - 객체지향 쿼리 언어
    • [Inflearn] JPA - 엔티티매핑
    • [Inflearn] JPA 시작하기 + JPQL이란?
    • [Inflearn] ORM, JPA란 무엇인가
    UL :)
    UL :)
    백엔드 개발자를 목표로 달리고 있습니다🔥

    티스토리툴바