SMALL
Dirty Checking이란?
코드에서 Entity의 값만 변경하였는데 DB 업데이트 쿼리가 발생하는것을 Dirty Checking 이라고 한다.
Dirty 란 상태의 변화가 생긴 정도를 의미한다.
JPA 에서 트랜잭션이 끝나는 시점에 변화가 있는 모든 entity 객체를 데이터 베이스에 자동으로 반영해준다.
Dirty Checking 내부 구조
위의 사진처럼 JPA 는 commit 하는 순간 내부적으로 flush 가 호출되고 이때 Entity 와 스냅샷을 비교 한다. 만약 비교하여 변경된 값이 있으면 update 쿼리를 쓰기 지연 SQL에 넣어둔다. 트랜잭션이 다 끝나면 commit() 를 하여 DB 에 저장을 한다.
주의사항
당연한 소리이지만 Dirty Checking 은 Entity 에만 적용이되고,
영속성 컨텍스트에 처음 저장된 순간 스냅샷을 저장해 놓고 트랜잭션이 끝나는 시점에 비교하여 변경된 부분을 쿼리로 생성하여 DB 에 날린다. 즉, 영속 상태가 아닐경우 값을 변경해도 DB 에 반영되지 않는다. 또한
트랜잭션이 없어도 데이터 반영이 일어나지 않는다.
아래의 코드를 보면서 이해하자.
약국의 Entity 이다.
@Entity
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Pharmacy {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column
private String pharmacyName;
@Column
private String pharmacyAddress;
@Column
private double x;
@Column
private double y;
}
여기서 약국 서비스를 만들어 update 하는곳에 트랜잭션 어노테이션을 붙이고 해당 entity 를 가져와 entity 를 수정하고 끝나면 트랜잭션이 끝나기 때문에 위와 설명했다시피 DB 에 반영이 된다.
@Slf4j
@Service
@RequiredArgsConstructor
public class PharmacyRepositoryService {
private final PharmacyRepository pharmacyRepository;
@Transactional
public void update(Long id, String name){
Pharmacy pharmacy = pharmacyRepository.findById(id).orElse(null);
if(pharmacy == null){
log.error("유효하지 않은 entity 입돠");
return;
}
pharmacy.setPharmacyName(name);
}
}
아래와 같이 테스트 코드를 짜본 결과 실제로 DB 값이 변경되는것을 확인할수 있었다.
@Test
void 더티채킹() {
//given
Pharmacy pharmacy = Pharmacy.builder()
.pharmacyName("약국테스트이름")
.pharmacyAddress("경기도 의정부시 호원동")
.x(10515562.32)
.y(51523963.25)
.build();
//when
Pharmacy returnpharmacy = pharmacyRepository.save(pharmacy);
service.update(returnpharmacy.getId(), "권씨약국"); //TODO:
//then
assertThat(pharmacyRepository.findById(returnpharmacy.getId()).get().getPharmacyName())
.isEqualTo("권씨약국");
}
반응형
LIST
'Spring' 카테고리의 다른 글
@Configuration 쓰고 안쓰고의 차이점 (0) | 2023.06.24 |
---|---|
Spring Retry (0) | 2023.06.19 |
Hibernate (0) | 2023.06.13 |
JPA 구조 및 이론 (2) | 2023.06.13 |
@Component / @ComponentScan (0) | 2023.06.13 |