더티 체킹 정의
더티 체킹(dirty checking)은 소프트웨어 개발에서 데이터 변경을 감지하고 이를 처리하는 기술입니다.
주로 데이터베이스나 UI 업데이트와 관련이 있습니다. 더티 체킹은 보통 데이터베이스나 객체의 속성을 감시하고, 이 속성이 변경되었는지 여부를 확인합니다. 변경 사항이 발생하면 이를 감지하고 이에 따라 필요한 작업을 수행합니다. 이것은 데이터베이스 시스템에서 레코드를 업데이트하거나, UI 프레임워크에서 화면을 업데이트하는 등의 작업에 활용됩니다.
더티 체킹은 주로 객체지향 프로그래밍에서 사용되며, 객체의 상태 변경을 추적하여 이를 적용하는 데 유용합니다. 주로 ORM(Object-Relational Mapping)과 같은 기술에서 데이터베이스 엔티티의 변경을 추적하는 데에 활용됩니다.
JPA 에서의 더티 체킹은 JPA가 엔티티를 관리하고 있는 동안에 엔티티의 상태 변경을 감지하는 메커니즘입니다. 이는 JPA가 트랜잭션 내에서 엔티티의 변경을 추적하고, 트랜잭션 커밋 시점에 변경된 내용을 데이터베이스에 자동으로 반영합니다.
* 트랜잭션에 대해서는 다음에 알아보기로 하고 넘어가자
더티 체킹 원리
중요한 키워드는 트랜잭션, 영속성 컨텍스트, 변경 감지 3가지이다.
더티 체킹 순서
- 트랜잭션 안에서 식별자( id )와 변경할 데이터를 명확하게 전달한다.
- 트랜잭션 안에서 영속 상태의 엔티티를 조회하고, 엔티티의 데이터를 직접 변경한다.
- 트랜잭션 커밋 시점에 변경 감지가 실행되고 데이터베이스에 자동으로 반영된다.
더티 체킹 예시 및 결론
더티 체킹 테스트 코드
더티 체킹 예시를 Test 코드로 알아보자.
PK가 1L 인 book이 저장되어 있다고 가정하자.
책 이름은 "책 v1" 이다.
이 책을 조회하고 트랜잭션안에서 변경하며 이후 커밋하면 어떤 변화가 일어나는지 확인해보자.
* 트랜잭션이 시작하고 끝나는 것을 보여주기 위해 EntityManager를 사용한 것이지만 실제로 @Transactional 어노테이션으로 더 쉽게 트랜잭션을 사용할 수 있다.
@SpringBootTest
class DirtyCheckingTest {
@Autowired
private ItemService itemService;
@PersistenceUnit
private EntityManagerFactory entityManagerFactory;
@Test
void updateItemByDirtyChecking() {
// given
Book book = new Book();
book.setId(1L);
book.setName("책 v1");
itemService.saveItem(book);
// when
EntityManager em = entityManagerFactory.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin(); //트랜잭션 시작
System.out.println("트랜잭션 시작");
Book findBook = (Book) em.find(Item.class, 1L);
findBook.setName("책 v2");
System.out.println("업데이트 아이템");
System.out.println("트랜잭션 커밋");
tx.commit(); //트랜잭션 커밋
//then
Book updateBook = (Book) em.find(Item.class, 1L);
Assertions.assertThat(updateBook.getName()).isEqualTo("책 v2");
}
}
결과 및 요약
트랜잭션이 시작된 후 조회된 entity 가 변경되면
커밋 된 이후 변경이 감지된 entity의 update 쿼리가 날아가 DB에 변경이 반영되는 것을 확인해 볼 수 있다.
'Spring > JPA' 카테고리의 다른 글
JPA N+1 문제와 해결 (0) | 2024.03.14 |
---|---|
즉시로딩과 지연로딩 - ORM에서의 데이터 조회 방식 (0) | 2024.03.11 |