hayu's 개발 일지

[TIL]240409 Dirty Checking 본문

프레임워크/spring

[TIL]240409 Dirty Checking

hayu00 2024. 4. 9. 21:11

Dirty Checking 이란?

  • 상태 변경 검사이다.
  • 영속성 컨테이너가 관리하는 엔티티의 상태를 감지해서 변경된 부분이 있다면 자동으로 트랜잭션이 끝나는 시점에 데이터 베이스를 반영하는 기능이다.
  • 여기서 Dirty는 엔티티 데이터의 변경된 부분을 뜻한다. 즉, Dirty checking 은 변경된 부분을 감지한다는 의미이다.

Dirty Checking 조건

영속성 컨텍스트에서 관리되는 엔티티

  • 영속성 컨텍스트는 엔티티를 처음 조회할 때 시작되며, 이후 변경을 감지한다.
  • 준영속 / 비영속 상태의 엔티티는 더티 체킹의 대상이 되지 못한다.

Transaction이 커밋되었을 때

  • 트랜잭션이 커밋되기 전까지 영속성 컨텍스트는 변경사항을 추적하기만 하고, 데이터 베이스에 반영하지 않는다. 따라서 트랜잭션이 커밋될 때 영속성 컨텍스트는 엔티티의 변경 상태를 데이터 베이스에 반영한다.

? @Transactional을 사용했는데 더티 체킹이 안되는 이유

@Transactional
    public Long enterMeeting(Member member, Long meetingId) {
				...
        eeting meeting = meetingRepository.findByIdAndCreator(meetingId, member)
                .orElseThrow(() -> new CustomException(ErrorCode.AUTHORITY_ACCESS));
       ...
    }
}         
  • 이 코드는 데이터 베이스로부터 조회한 객체이다. 그러나 @Transactional 외부에서 주입된 현재 메서드의 영속성 컨텍스트와 관련없는 엔티티이다.
@Transactional
public Long enterMeeting(Member member, Long meetingId) {
    // 회원 조회
    Member member1 = memberRepository.findById(member.getId())
            .orElseThrow(() -> new CustomException(ErrorCode.NOT_EXIST_USER));

    // 회의 조회
    Meeting meeting = meetingRepository.findById(meetingId)
            .orElseThrow(() -> new CustomException(ErrorCode.MEETING_NOT_FOUND));

    // MeetingMember 엔티티 생성
    MeetingMember meetingMember = MeetingMember.builder()
            .member(member1)
            .meeting(meeting)
            .build();

    // 생성된 MeetingMember 엔티티를 영속성 컨텍스트에 저장
    meetingMemberRepository.save(meetingMember);

    // 트랜잭션 커밋
    return meeting.getId();
}
  • 메서드를 호출하는 상위 계층에서 조회하지 않고 메서드 내부에서 엔티티를 조회하면 된다.

→ 영속 상태의 엔티티만 더티 체킹이 적용되기 때문이다.

 

참고 자료

- https://velog.io/@hyunho058/Spring-Data-JPA-%EB%8D%94%ED%8B%B0-%EC%B2%B4%ED%82%B9Dirty-Checking

- https://everydayyy.tistory.com/157

- https://daegwonkim.tistory.com/446

- https://junior-datalist.tistory.com/349