JPA에서 더티 체킹(Dirty Checking)이란?
JPA의 더티 체킹(Dirty Checking)은 영속성 컨텍스트가 관리하는 엔티티의 상태를 자동으로 감지하고, 변경된 부분이 있다면 트랜잭션 커밋 시점에 데이터베이스에 반영하는 기능입니다. 이는 개발자가 직접 SQL을 작성하지 않아도 JPA가 엔티티의 변경을 감지하고 처리할 수 있도록 돕는다.
영속성 컨텍스트와 더티 체킹
JPA에서 엔티티는 영속성 컨텍스트에 의해 관리된다. 영속성 컨텍스트는 데이터베이스와 관련된 엔티티 객체의 상태를 관리하는 일종의 캐시(1차 캐시)라고 할 수 있다. 엔티티가 영속성 컨텍스트에 등록되면 영속 상태가 되고, 이때 영속 상태의 엔티티는 데이터베이스에 저장된 값과 연결되며, JPA가 그 상태를 추적한다.
더티 체킹의 동작 원리 (중요)
- 영속성 컨텍스트는 엔티티가 처음 등록되었을 때의 스냅샷(초기 상태)을 유지한다.
- 엔티티의 필드 값이 변경되면, 스냅샷과 현재 상태를 비교하여 변경된 부분(Dirty)을 감지한다.
- 트랜잭션이 커밋되는 시점에 변경된 데이터를 반영하기 위한
UPDATE
쿼리를 자동으로 생성하고 실행한다.
더티 체킹의 예제 코드
아래는 JPA의 더티 체킹을 간단히 보여주는 코드이다.
1. 영속 상태의 엔티티 조회
EntityManager em = ...;
Member member = em.find(Member.class, 1L); // id가 1인 Member 조회
위 코드에서 em.find
를 호출하면, 데이터베이스에서 ID가 1인 Member
엔티티를 조회하고 영속성 컨텍스트에 등록한다.
2. 엔티티의 값 변경
member.setName("New Name"); // 영속 상태 엔티티의 name 필드를 변경
엔티티의 필드 값을 변경하면, JPA는 영속성 컨텍스트에 저장된 스냅샷과 변경된 현재 상태를 비교하여 변경 사항을 기록한다.
3. 트랜잭션 커밋 시점
em.getTransaction().commit(); // 트랜잭션이 끝나는 시점에 더티 체킹 발생
트랜잭션이 커밋되는 순간, JPA는 기록된 변경 사항에 대해 UPDATE
SQL 쿼리를 생성하여 데이터베이스에 반영한다.
더티 체킹의 특징
- 자동화된 변경 감지: 더티 체킹은 개발자가 직접 SQL을 작성하지 않고도 데이터베이스와 엔티티 간의 동기화를 관리한다.
- 최적화: 변경되지 않은 필드는
UPDATE
대상에 포함되지 않으므로, 효율적인 쿼리가 실행된다. - 투명성: 변경 사항이 자동으로 감지되므로, 코드가 간결해지고 유지보수가 용이하다.
주의해야 할 점
- 성능 문제: 엔티티가 많을 경우, 더티 체킹 과정에서 많은 연산이 필요하므로 성능 이슈가 발생할 수 있다. 이를 해결하기 위해 배치 처리를 고려하거나 쿼리를 직접 작성하는 방식도 고려해볼수 있다.
- 명시적인 플러시: JPA의 자동 플러시는 트랜잭션 커밋 이전에도 실행될 수 있으므로, 플러시 타이밍을 명확히 이해해야 한다.
- 비영속 상태 객체: 영속 상태가 아닌 엔티티는 더티 체킹의 대상이 되지 않으므로, 영속 상태의 체크가 필요하다.
'IT > JPA' 카테고리의 다른 글
[JPA] - 영속성 컨텍스트 (Persistence Context) (0) | 2024.12.13 |
---|---|
[JPA] - 지연 로딩(Lazy Loading)과 즉시 로딩(Eager Loading) (0) | 2024.12.12 |