Geneuin
Geneuin
1 min read

Categories

JPA 더티체킹

영속성 컨텍스트의 특징 중 더티체킹(Dirty Checking) 에 대해서 예제를 통해 알아보도록 하겠습니다.

2021-05-18-더티채킹1

예제를 위해 DB에 MEMBER라는 테이블로 위와 같은 값을 설정하였습니다.

위 데이터를 기준으로 코드를 작성해 보겠습니다.

Main

public class jpaMain {

    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        tx.begin(); // [트랜잭션] 시작
        try {
            Member member = em.find(Member.class,1L);

            member.setName("Test!!"); // 엔티티만 변경

            tx.commit(); // [트랜잭션] 커밋
        }catch (Exception e){

        }
    }
}

코드를 확인해 보면 member의 name값만 변경해 줄 뿐 다른 액션은 하지 않았습니다.

하지만 작동은 어떻게 될까요 ?

코드를 수행해 보면 아래와 같은 로그를 확인 할 수있습니다.

2021-05-18-더티채킹2

  • select 문으로 member를 찾고
  • member의 값을 업데이트 하는 쿼리가 실행되는 것을 볼 수 있습니다.
  • 실제로 DB값이 업데이트 되는걸 다음과 같이 확인해 볼 수있습니다.

2021-05-18-더티채킹3

Why ?

어째서 persist나 save와 같이 값을 변경해 준뒤 따로 저장을 해주지 않아도 update가 실행되는 것일까요 ?

이유는 바로 JPA의 영속성 컨텍스트 때문입니다.

2021-05-18-더티채킹4

위 사진은 트랜잭션 commit 시 동작하는 내부 매커니즘입니다.

  1. JPA는 엔티티를 조회하면 해당 엔티티의 조회 상태 그대로 영속컨테이너에 스냅샷을 만들어놓습니다. ( find() )
  2. commit 시 내부적으로 flush 라는 함수가 실행됩니다.
    • flush란 ? 영속성 컨텍스트의 변경내용을 데이터베이스에 반영하는 것을 의미합니다.
  3. 그리고 트랜잭션이 끝나는 시점에는 이 스냅샷과 비교해서 다른점이 있다면 Update 쿼리를 생성합니다.
  4. 최종적으로 데이터베이스에 쿼리를 반영하게됩니다.

이러한 동작이 실행되기 위해선 다음과 같은 조건이 충족되어야 합니다.

  • 영속 상태(Managed) 안에 있는 엔티티인 경우
  • Transaction 안에서 엔티티를 변경하는 경우

결론

Dirty Checking 이란 ?

  • 엔티티의 변경이 일어나면, 엔티티의 처음 상태와 비교해 변경 내용을 자동으로 데이터베이스에 반영하는 JPA 특징이다.

감사합니다.


  • references:
  • Written by: 박상길 (fkdl3919@gmail.com)
  • reporting date: 2021-05-16