[Spring] 영속성 컨텍스트 (3)

이연우·2025년 7월 28일

TIL

목록 보기
69/100

🔍 변경 감지 (Dirty Checking)

  • 영속 상태의 엔티티를 수정하면 JPA가 처음 조회했을 때의 상태(스냅샷) 와 비교하여
    변경된 필드를 자동으로 감지하고 트랜잭션 커밋 시 UPDATE SQL을 실행

✅ 동작 원리

  1. em.find() → DB에서 조회 후 스냅샷 저장

  2. Java 코드에서 필드 변경

  3. transaction.commit()

    • 스냅샷과 현재 값 비교
    • 변경된 필드가 있으면 UPDATE SQL 자동 실행

📌 예시 코드 요약

Tutor tutor = em.find(Tutor.class, 1L); // DB 조회 및 스냅샷 저장
tutor.setName("수정된 이름");           // 필드 변경

// em.persist(tutor); ❌ 필요 없음

transaction.commit(); // UPDATE SQL 자동 실행

🧠 중요한 점

  • em.persist()는 새 엔티티 저장 시 사용하는 메서드
  • 영속 상태에서는 필드 수정만으로도 자동 반영
  • JPA는 마치 Java Collection처럼 사용 가능

📦 내부 구조

  • 📸 스냅샷(Snapshot)
    : Entity의 초기 상태 복사본

  • 값을 조회한 최초 시점의 상태를 임시로 저장

  • 🔄 변경 비교
    : 커밋 시점에 현재 값과 스냅샷 비교 후 SQL 생성

if (!snapshot.equals(current)) {
    // UPDATE SQL 생성
}

🗑️ 삭제도 동일 구조

em.remove(tutor); // 삭제 예약
transaction.commit(); // 이 시점에 DELETE SQL 실행

💡 삭제도 커밋 시점에 SQL이 실행됨


💨 flush란?

  • 영속성 컨텍스트에서 관리 중인 변경 내용을 데이터베이스에 동기화하는 작업
  • SQL을 실제 DB로 반영하는 시점을 조절

⏱️ flush 호출 시점

방식설명
자동transaction.commit() 시 자동 호출됨
수동em.flush()로 원하는 시점에 직접 호출 가능

📌 예시 코드 요약

Tutor tutor = new Tutor(1L, "wonuk", 100);
em.persist(tutor);

em.flush(); // INSERT SQL 즉시 실행

transaction.commit(); // INSERT 이미 실행됨, 추가 SQL 없음

🔄 flush vs commit

구분flushcommit
SQL 실행 여부변경 내용 DB 반영flush 포함 + 트랜잭션 종료
트랜잭션 종료 여부
수동 호출 가능❌ (자동)

🧠 요약 정리

항목개념동작 시점비고
🧾 변경 감지Entity 수정 자동 추적commit()UPDATE SQL 자동 생성
📸 스냅샷최초 조회 상태 복사본find() 직후비교 기준
💨 flush변경 내용 즉시 반영flush() 또는 commit()트랜잭션은 유지
🧹 remove삭제 예약remove()commit()DELETE SQL 실행됨

0개의 댓글