JPA 더티 체킹(Dirty Checking) 이란?

Jiny·2021년 5월 5일
0

더티 체킹(Dirty Checking) 이란?

더티체킹은 Transaction 안에서 엔티티의 변경이 일어나면, 변경 내용을 자동으로 데이터베이스에 반영하는 JPA 특징이다.

Dirty Checking의 뜻은 변경 감지 정도로 생각할 수 있다. 즉, 변경을 감지해서 DB에 반영한다.

데이터베이스에 변경 데이터를 저장하는 시점

  1. Transaction Commit
  2. EntityManager Flush
  3. JPQL 사용

JPA에서는 트랜잭션이 끝나는 시점에 변화가 있는 모든 엔티티 객체를 데이터베이스에 자동으로 반영해준다.
변화의 기준은 최초 조회 상태

JPA에서는 엔티티를 조회하면 해당 엔티티의 조회 상태 그대로 스냅샷을 만든다.
트랜잭션이 끝나는 시점에 스냅샷과 현재의 상태를 비교해 다른점이 있다면 Update Query를 데이터베이스로 전달한다.

더티체킹을 진행하는 검사의 대상
영속성 컨텍스트가 관리하는 엔티티를 대상으로 한다.

  • detach 된 엔티티 (준영속)
  • DB에 반영되기 전 처음 생성된 엔티티 (비영속)

준영속/비영속 상태의 엔티티는 더티 체킹에 해당사항이 없다.
값을 변경해도 데이터베이스에 반영되지 않음.

@Transactional  
public void cancelOrder(Long orderId) {  
    //주문 엔티티 조회  
    Order order = orderRepository.findOne(orderId);  

    //주문 취소  
    order.cancel();  
}

위와 같은 코드의 경우에 update 쿼리에 관한 코드가 전혀 없는데도 불구하고, 실행 시 정상적으로 내용이 update 됨을 확인할 수 있다.

@DynamicUpdate

변경 감지는 엔티티 객체 관점에서 보면 원하는 내용만 변경한다.
하지만, 기본적으로 Dirty Checing이 실행하는 SQL은 변경된 엔티티의 모든 내용을 Update Query로 만들어서 전달한다.

전체 필드를 업데이트 하는 방식의 장점?

  • 생성되는 쿼리가 같아 부트 실행 시점에 미리 만들어서 재사용이 가능하다.
  • 데이터베이스 입장에서 쿼리 재사용이 가능하다. (동일한 쿼리를 받으면 이전에 파싱된 쿼리를 재사용)

필드가 많을 겨우 전체 필드 Update 쿼리가 부담스러울 수 있음.
이런 경우에 @DynamicUpdate어노테이션을 사용하여 변경 필드만 반영되도록 할 수 있다.
아래와 같이 엔티티의 최상단에 @DynamicUpdate를 선언해주면 된다.

@Getter
@Entity
@NoArgsConstructor
@DynamicUpdate
public class Category {  

    @Id @GeneratedValue  
    @Column(name = "category_id")  
    private Long id;  

    private String name;
profile
공부하는 초보 웹 개발자, 생각나는 걸 씁니다.

0개의 댓글