코딩과 결혼합니다

[JPA] 영속성 관리 - 내부 동작 방식 본문

2세/JPA

[JPA] 영속성 관리 - 내부 동작 방식

코딩러버 2024. 2. 6. 20:49
728x90

엔티티 매니저

DB와의 상호작용을 담당하는 핵심 컴포넌트. 영속성 컨텍스트를 관리하며, 엔티티의 생성, 수정, 삭제, 조회 등의 작업을 처리한다.

 

영속성 컨텍스트

엔티티의 상태를 관리하는 공간. 영속성 컨텍스트는 엔티티 매니저를 통해 접근하며, 엔티티의 영속성을 보장하고 엔티티의 변경을 추적한다.

엔티티 매니저를 생성하면 그 안에 1대1로 영속성 컨텍스트가 생성된다.

엔티티의 생명주기

비영속 : 영속성 컨텍스트와 전혀 관계가 없는 새로운 상태
영속 : 영속성 컨텍스트에 관리되는 상태
준영속 : 영속성 컨텍스트에 저장되었다가 분리된 상태
삭제 : 삭제된 상태
//엔티티를 생성한 상태(비영속)  
Member member = new Member();  
member.setId("member1");  
member.setUsername("회원1");

//엔티티를 영속  
em.persist(member);

*영속 상태가 되었다고 해서 바로 DB에 쿼리가 날라가는게 아니다.

 

영속 컨텍스트의 이점

  1. 1차 캐시
    • 영속성 컨텍스트는 엔티티를 조회할 때, 처음으로 조회한 엔티티를 1차 캐시에 저장한다.
    • 이후 동일한 엔티티를 조회할 때 DB에 직접 접근하는 대신 1차 캐시에서 엔티티를 가져온다.
    • 트랜잭션 안에서 찰나의 순간에 이뤄지는 것으로 크게 성능을 향상시키는 것은 아니다.
  2. 동일성 보장
    • 동일한 식별자를 가진 엔티티가 1차 캐시에 이미 존재하는 경우, 해당 엔티티의 참조를 반환하여 동일성을 보장.
    • 같은 엔티티를 여러 곳에서 사용할 때 데이터 일관성과 예상치 못한 문제를 방지할 수 있다.
  3. 트랜잭션을 지원하는 쓰기 지연
    • 엔티티의 변경은 트랜잭션을 커밋할 때까지 지연되어 데이터베이스에 반영되지 않는다.
    • 여러 개의 변경 작업을 하나의 트랜잭션으로 묶어 일관성을 유지하고, DB에 접근하는 횟수를 최소화할 수 있다.
  4. 변경 감지
    • 엔티티의 상태변화를 추적하여 변경된 부분만을 데이터베이스에 업데이트하므로, 수정 작업을 수동으로 처리할 필요가 없다.
    • flush는 변경된 엔티티를 DB에 동기화하는 역할을 한다.(변경 내용을 DB에 반영)
  5. 지연 로딩
    • 엔티티를 실제로 사용할 때까지 데이터베이스에서 로딩을 지연시킨다.
    • 필요한 시점에만 로딩하여 성능을 최적화할 수 있다.

Flush

  1. 트랜잭션 커밋 : 트랜잭션을 커밋할 때, 영속성 컨텍스트는 변경된 엔티티를 데이터베이스에 동기화 하기 위해 플러시를 시행한다.// 플러시 자동 호출
  2. 명시적인 플래시 호출 : 개발자가 영속성 컨텍스트에 쌓인 변경 내용을 명시적으로 데이터베이스에 반영하고자 할때, flush() 메서드를 호출하여 플러시를 실행할 수 있다. // 플러시 직접 호출
  3. JPQL 쿼리 실행 // 플러시 자동 호출

flush 동작 방식

  1. 더티 체킹 : 플러시가 실행되면 영속성 컨텍스트는 변경된 엔티티를 추적하여 DB에 업데이트 해야할지 판단. 이 때 더티체킹 과정이 수행된다.
  2. SQL 쿼리 생성 : 변경된 엔티티가 확인되면, 해당 엔티티에 대한 적절한 SQL 쿼리가 생성된다. 이때 변경된 필드에 대한 UPDATE 쿼리가 생성된다.
  3. SQL 쿼리 실행 : 생성된 SQL 쿼리는 데이터베이스에 전달되어 실행된다. DB는 변경된 내용을 받아들여 업데이트.
**플러시는 영속성 컨텍스트를 비우지 않는다.
**트랜잭션이라는 작업 단위가 중요하다. -> 커밋 직전에만 동기화 하면