JPA

[JPA] 변경감지 Dirty Checking, @Transactional, @DynamicUpdate

Karla Ko 2024. 1. 18. 17:37
728x90

변경감지

변경감지는 트랜잭션 커밋시 영속화된 Entity에서 가지고 있었던 최초 정보(스냅샷)와 바뀐 Entity 정보를 비교해서 바뀐 부분을 update 해주는기능

1. 클라이언트에서 식별자를 포함한 데이터를 넘김
2. 식별자(id)를 통해서 DB에서 데이터 조회 후, 조회된 데이터를 영속화
. 클라이언트에서 넘어온 값들을 토대로 기존의 데이터를 새로운 데이터로 변경 : 변경점 발생
4. 트랜잭션 커밋
5. JPA에서 변경점들을 확인하고 변경해야할 것에 맞게 DB 쿼리를 실행 : 변경 감지 (Dirty checking)

변경감지 조건

  • 변경하려는 Entity가 영속 상태여야함 (영속성 컨텍스트 안에 관리되는 상태)
  • 트랜잭션 안에 묶여 있어야함
  • 트랜잭션이 제대로 커밋되어야함 (그래야 flush가 작동하기 때문)

 

 

@Transactional

@Transactional
public void test(PersonDto personDto){
    Person savedPerson = repository.save(personDto.to(personDto));

    int age = 30;
    savedPerson.setAge(age);

}

 

이 있는 경우에는 해당 메소드가 트랜잭션으로 묶여있어 메소드가 끝나는 지점에 트랜잭션 커밋이 발생하게 되고 flush가 자동으로 작동

save 없이 insert 이후 update 쿼리 실행됨

 

@DynamicUpdate

이때, 위에서 업데이트 시 변경한 내용은 age 하나지만, update 쿼리에는 person_name필드또한 update됨

  • 기본적으로 JPA는 전체 필드를 업데이트 하는 방식
  • Dirty Checking으로 생성되는 update 쿼리는 기본적으로 모든 필드 update

수정 쿼리가 항상 동일하게 만들어지므로, 생성되는 쿼리가 같아 부트 실행시점에 미리 update 쿼리를 만들어서 재사용 가능
데이터베이스 입장에서 동일한 쿼리를 받아 이전에 파싱된 쿼리의 재사용 가능

하나의 엔티티에 필드가 많아져 update가 부담스러워지고, 변경된 필드만 upadte 쿼리로 적용하고 싶다면 @DynamicUpdate 어노테이션을 사용

 

수정된 필드만 update됨

 

 

728x90