변경 감지란?
영속성 컨텍스트에 의해 관리되는 영속 상태의 객체의 필드 값이 수정되면,
JPA는 이를 자동으로 감지하여 해당 변경 사항이 DB에 반영돼야 함을 인지합니다.
즉, 영속 상태의 객체가 수정될 때 JPA는 이를 변경된 것으로 판단하고 적절한 UPDATE SQL를 만들어내는 과정입니다.
변경 감지 조건 :
1. 트랜잭션이 열려 있다.
2. 엔티티가 영속성 컨텍스트에 존재해야 한다.
!트랜잭션을 연다
!엔티티를 영속성 컨텍스트에 올림 = 영속화 시킨다
엔티티 영속화 방법에는 대표적으로 find 같은 조회 메서드 외에도..
persist(), merge(), save() JPQL 과 QueryDSL 쿼리가 있다.
find 조회하면 영속성 컨텍스트 내부(1차 캐시)를 뒤져본다
있으면 1차 캐시에 있는 값을 return, 없으면 DB를 확인하러 간다.
1차 캐시란?
영속성 컨텍스트 내부에서 엔티티 인스턴스들을 저장하는 공간이다.
주로 Map<Pk, Entity>의 형태로 저장한다.
영속성 컨텍스트가 내부적으로 1차 캐시를 사용한다고 생각하면 된다.
이정도만 이해해도 전혀 문제 없다.
**스냅샷**이 생성됨, 이는 변경 감지에 사용된다
스냅샷 (=영속화 된 시점의 해당 엔티티의 필드를 모두 복제한 것)
스냅샷은 트랜잭션 커밋 시점에 엔티티 필드와 비교되어 UPDATE 쿼리가 작성된다.
쉽게, 영속성 컨텍스트에 처음 들어왔을 때와 마지막 모습의 차이만큼 UPDATE 쿼리 생성
!영속 상태의 엔티티의 필드 값을 변경함: - 대표적으로는 서비스 레이어 등등..
!flush()가 호출된 시점에 변경된 엔티티들이 스냅샷과 비교됨
내부적으로 flush()가 호출되면 JPA는 영속성 컨텍스트 내의 모든 엔티티를 스냅샷과 비교하여 변경된 부분이 있는지 확인합니다.
!쓰기 지연 저장소에 update 쿼리들이 쌓이고, 데이터베이스에다 flush 해버린다
→ 데이터베이스에 쿼리가 날라가서 값이 바뀌는 것
(rollback이 가능하여 임시적이라 말하겠음)
!트랜잭션이 커밋(종료), 데이터베이스에 반영(확정)
→ rollback이 불가능, 트랜잭션 끝나면서 확정시켜버림
트랜잭션이 닫히고, 영속성 컨텍스트도 함께 정리됨..
Flush와 Commit의 차이점
flush : 영속성 컨텍스트와 데이터베이스 간 임시 동기화(트랜잭션 rollback 가능)
transaction commit : 확정 (트랜잭션 rollback 불가능!)

끝.