728x90
JPA에서 더티 체킹과 트랙잭션의 필요성을 인지하지 못한다면 비지니스 로직에서 다루는 엔티티 데이터가 꼬이는 경우가 발생한다.
이런 경우를 방지하지위해 더티 채킹을 알아야 한다.
더티 (Dirty) ? - 상태의 변화가 생긴 정도
더티 체킹 (Dirty Checking) ? - 상태 변경 검사
JPA에서는 트랙잭션이 끝나는 시점에 변화가 있는 모든 엔티디 객체를 데이터베이스에 자동으로 반영해준다.
→ 변화의기준 : 최초 조회 상태
JPA에서의 Dirty Checking
- 엔티티를 조회하면 해당 엔티티의 조회 상태 그대로 스냅샷을 만든다.
- 트랜잭셔니 끝나는 시점에는 이 스냅샷과 비교하여 다른점이 있다면 Update Query를 데이터베이스로 전달한다.
- 이런 상태에 변경 검사의 대상은 영속성 컨텍스트가 관리하는 엔티티에만 적용된다.
- detach된 엔티티 (준영속)
- DB에 반영되기 전 처음 생성된 엔티티(비영속)
- 준영속/비영속 상태의 엔티티는 Dirty Checking 대상에 포함되지 않는다.
- 즉, 값을 변경해도 데이터베이스 반영되지 않는다.
- 이런 상태에 변경 검사의 대상은 영속성 컨텍스트가 관리하는 엔티티에만 적용된다.
변경 부분만 Update하고 싶은 경우
더티 채킹으로 생성되는 Upadte 쿼리는 기본적으로 모든 필드를 업데이트한다.
JPA에서는 전체 필드를 업데이트하는 방식이 기본값이다.
- 장점
- 생성되는 쿼리가 같아 부트 실행시점에 미리 만들어서 재사용가능하다.
- 데이터베이스 입장에서 쿼리 재사용이 가능하다.
- 동일한 쿼리를 받으면 이전에 파싱된 쿼리를 재사용한다.
하지만 필드가 20~30개 이상인 경우 전체 Update 쿼리가 비효율적일 수가 있다.
( 많은 복잡도를 가진 서비스의 경우에도 필드가 15개 이하이므로 20~30개의 필드가 있을 경우 바람직하지 않은 테이블이다. )
이런 경우에는 @DynamicUpdate 로 변경 필드만 반영되도록 할 수 있다.
@Getter
@NoArgsConstructor
@Entity
@DynamicUpdate // 변경한 필드만 대응
public class Pay {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String tradeNo;
private long amount;
위와 같이 @DynamicUpdate 를 선언해주면 가능하다.
'Spring' 카테고리의 다른 글
DBMS의 트랜잭션과 @Transactional (1) | 2022.09.23 |
---|---|
JPA와 Spring Data JPA (0) | 2022.04.24 |
Sring Boot + Redis를 이용한 Cachcing (0) | 2022.04.10 |
[JPA] Bulk Insert 적용기 (0) | 2022.01.06 |