728x90
✅ Write-Behind (쓰기 지연) 란?
JPA의 핵심 기능 중 하나로, 엔티티 객체의 변경을 바로 DB에 반영하지 않고 트랜잭션이 커밋될 때 한 번에 반영하는 전략이야.
💡 왜 쓰기 지연을 사용할까?
- 성능 최적화
→ 객체를 여러 번 수정할 때마다 DB에 SQL을 날리면 성능이 떨어져.
→ JPA는 SQL을 "모아서 한 번에" 보냄으로써 성능을 높여줘. - 트랜잭션 관리 효율
→ 트랜잭션 도중 예외가 발생하면, 실제 DB에는 반영되지 않았기 때문에 롤백이 쉬움.
💡 예시로 이해해보자
@Transactional
public void updateUser() {
User user = em.find(User.class, 1L);
user.setName("홍길동");
user.setEmail("gildong@example.com");
// 아직 DB에는 아무 일도 일어나지 않음!
// 변경 사항은 영속성 컨텍스트 안에만 존재
// 여기서 트랜잭션이 커밋되면 → 한 번에 UPDATE SQL 2개가 나감!
}
📌 무슨 일이 벌어졌을까?
- find()로 가져온 user는 영속성 컨텍스트에 등록됨.
- setName(), setEmail()로 데이터를 변경함.
- 이때 JPA는 바로 SQL을 실행하지 않음.
- commit() 시점에 변경된 필드를 감지하여 SQL을 생성함.
- UPDATE user SET name='홍길동' WHERE id=1
- UPDATE user SET email='gildong@example.com' WHERE id=1
✔️ 이것이 쓰기 지연(Write-Behind) 이고,
변경 감지(Dirty Checking)와 함께 작동해.
🔁 함께 기억할 개념
개념 | 설명 |
Dirty Checking | 엔티티 객체의 상태가 변경됐는지 감지함 |
1차 캐시 | 트랜잭션 동안 EntityManager 내부에 객체를 저장하는 캐시 |
Write-Behind | 변경된 데이터를 DB에 바로 쓰지 않고 커밋 시점에 반영함 |
🎯 언제 flush가 일어날까?
JPA는 다음과 같은 시점에 쓰기 지연된 SQL을 DB에 보내:
- 트랜잭션 커밋 시점
- JPQL / Native Query 실행 전
- flush() 명시적 호출 시
🚨 단점은 없을까?
- 커밋 시점까지 DB에 반영되지 않으므로, 중간에 DB에 반영된 결과를 확인할 수 없음.
- 중간 SQL 실행 순서가 중요한 로직에는 flush()를 수동으로 호출해야 함.
728x90
'프로그래밍 > Spring' 카테고리의 다른 글
커밋, 롤백, 트랜잭션, flush()과 커밋의 차이점 (0) | 2025.04.07 |
---|---|
변경 감지 (Dirty Checking)란? (0) | 2025.04.07 |
⚾️ JPA 1차 캐시 (First-Level Cache) 완전 정복 (0) | 2025.04.07 |
🌿 JPA의 핵심! Persistence Context(영속성 컨텍스트) 완벽 정리 (0) | 2025.04.07 |
🌱 Spring Data JPA 완전 정복 가이드 (0) | 2025.04.04 |