👩🏻‍💻 Programming/SpringBoot

JPA 더티 체킹(Dirty Checking)

한국의 메타몽 2021. 10. 2. 21:47

 

Dirty Checking이란?

 

Transaction안에서 엔티티의 변경이 일어나면 변경된 내용을 자동으로 DB에 반영하는 JPA 특성이다.

 

좀더 디테일한 설명은 다음과 같다.

 

  • JPA는 엔티티 매니저가 엔티티를 저장 / 조회 / 수정 / 삭제한다. 
  • 그런데 엔티티 매니저가 제공하는 메소드들을 보면 저장 (persist) / 조회(find) / 삭제 (delete)로 수정에 해당되는 메소드가 없다.
  • 대신에 수정에 해당되는 더티 체킹 (Dirty Checking)을 지원한다.
  • 더티 체킹은 Transaction 안에서 엔티티의 변경이 일어나면 변경으 자동으로 DB에 반영하는 JPA 특성이다.
  • DB에 변경 데이터를 저장하는 시점은 (1) Transaction Commit 시점 (2) EntityManager Flush 시점 (3) JPQL 사용 시점 이다.
  • 또한, 영속성 컨텍스트 (Persistence Context) 안에 있는 엔티티를 대상으로 더티 체킹이 일어난다.
  • 여기서 Dirty란 "Entity 데이터의 변경된 부분"으로 해석하면 된다.

 

 

더티체킹의 이슈

 

엔티티의 변경이 일어나면 자동으로 DB에 변경사항을 업데이트해주니 어찌보면 편하게 보일 수 있다.

하지만 반례가 존재하는데, 예를들어 Transaction 내부에서 데이터를 참조하기 위해 Select를 한 Entity가 있을 경우, 일일이 더티체킹을 하는 과정이 포함된다. 데이터가 적을경우에는 상관없지만, 수십, 수백만건의 데이터를 조회하는데 배치(Batch) 로직에서 더티체킹까지 포함된다면 시간이 굉장히 오래걸릴 것이다. 이런 경우에는 더티체킹을 하지 않고 데이터를 조회해야하는데, 방법은 아래와 같다.

 

    @Transactional(readOnly = true) // readonly 추가
    public void updateSomething() {
        List<Comment> comments = commentRepository.findAll();

        for (Comment comment : comments) {
            comment.setComment("별로예요");
        }
    }

위와같이 Transaction의 readOnly 속성을 true로 변경해주면된다.

이렇게하면 flush를 manul로, 즉, 수동으로 해주기 때문에 더티 체킹이 스킵된다.

 

 

참고 사이트

 

라이언곰돌이푸 - JPA 더티 체킹이란?

 

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

JPA(Java Persistence API)를 사용하면서 더티 체킹과 트랜잭션의 관계에 대해서 알고 있지 않으면, 비즈니스 로직에서 다루는 엔티티 데이터가 꼬이는 경우가 발생합니다. 데이터가 꼬이는 경우를 방

interconnection.tistory.com