CS

[JPA] 더티 체킹(dirty checking) 정리

jungmin.park 2023. 12. 11. 20:24

 

JPA의 더티체킹이란 무엇인가요?

더티 체킹이란

 

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

따라서 개발자가 update에 관련된 쿼리를 작성하지 않아도 되기 때문에, 코드의 복잡성을 줄일 수 있다는 특징이 있다.

 

더티체킹의 순서

  • 영속성 컨텍스트는 엔티티를 조회할 때 시작되며, 이후 변경을 감지한다.
    • 준영속/비영속 상태의 엔티티는 더티 체킹의 대상이 되지 못한다.
  • Transaction이 커밋되기 전까지는 영속성 컨텍스트는 변경 사항을 추적하고, DB에 반영하지 않는다.
  • Transaction이 커밋될때 영속성 컨텍스트는 엔티티의 변경사항을 DB에 반영한다.

 

@Transactional
	public TicketResponseDto reserveTicket(User user, TicketRequestDto ticketRequestDto) {
		TicketInfo ticketInfo = ticketInfoRepository.findById(ticketRequestDto.getTicketInfoId()).get();
		Ticket ticket = new Ticket(user, ticketInfo, ticketRequestDto);
		try {
			ticketInfo.updateStock(-1L); // 티켓 총 개수 차감
			ticketRepository.save(ticket);
		}catch (Exception e){
			throw new TicketReserveException("예약을 할 수 없습니다.");
		}
		return new TicketResponseDto(ticket);
	}

 

@Getter
@Setter
@Entity
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "ticket_info")
public class TicketInfo {
	....

    public void updateStock(Long amount) {
            if (this.stock + amount < 0) {
                throw new OutOfStockException("재고 소진");
            }
            this.stock += amount;
        }
 }

 

티켓을 예약하면 잔여 좌석 수에서 1을 차감하는 로직이다.

 

Postman으로 API를 실행했을때, findBy~로 TicketInfo 객체를 찾고, 자동으로 update쿼리를 날린다.

 

더티체킹을 통해 자동으로 생성된 update쿼리는 기본적으로 모든 필드를 업데이트한다.

실제 stock만 아닌 ticketinfo에 있는 모든 칼럼을 다 업데이트 한다는 의미이다.

 

따라서, 변경된 필드만 업데이트 되도록 하고자 하면 다음과 같이 @DynamicUpdate 어노테이션을 붙임으로써 가능하다.

@Getter
@DynamicUpdate
@Setter
@Entity
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "ticket_info")
public class TicketInfo {
	....

    public void updateStock(Long amount) {
            if (this.stock + amount < 0) {
                throw new OutOfStockException("재고 소진");
            }
            this.stock += amount;
        }
 }

 

@DynaminUpdate 어노테이션을 붙이면 stock만 업데이트 된다.

 

 

더티체킹은

영속성 컨테이너가 관리하는 엔티티의 상태를 감지해서, 변경된 부분이 있다면 자동으로 트렌젝션이 끝나는 시점에 데이터베이스 반영하는 기능입니다. 개발자가 update에 관련된 쿼리를 작성하지 않아도 되기 때문에, 코드의 복잡성을 줄일 수 있다는 장점이 있습니다. 
영속성 컨텍스트는 엔티티 조회할때 시작하며 Transactional이 커밋될때 엔티티의 변경된 상태를 DB에 반영합니다.