⇒ 블로그가 의문점을 잘 정리해두었으니 꼭 읽어볼 것을 추천
clear**를 호출하면 영속성 컨텍스트의 캐시된 엔터티들이 모두 제거되므로, 주의해서 사용flush**를 호출하면 영속성 컨텍스트의 변경 내용이 데이터베이스에 반영되므로, 데이터베이스와의 일관성을 유지flush**를 호출해도 영속성 컨텍스트에 있는 엔터티는 여전히 관리되는 상태flush()메서드 안의 flush
flush는 영속성 컨텍스트의 변경내용을 데이터 베이스에 동기화하는 것이다.
DB commit은 해당 트랜잭션이 commit 될 때 발생되며 이 때 flush()가 호출된다. 여기서 주의할 점은, 트랜잭션은 작업단위임으로 한 트랜잭션 내에서 아무리 많이 flush가 발생해도 DB commit은 발생하지 않는다!
트랜잭션의 범위가 종료되면 영속성 컨텍스트는 완전히 비워지고, 이후 새로운 트랜잭션과 함께 새로운 영속성 컨텍스트가 생성된다
flush() 호출 시 내부 로직
그러면 왜 트랜잭션이 커밋될 때 flush()가 자동 호출되는가?
flush() 와 같이 remove()의 내부 로직도 보자
엔티티를 삭제하기 위해 먼저 삭제 대상의 엔티티 조회
em.find()를 실행
엔티티가 영속 컨텍스트 내부 캐시에 등록되어 있지 않을 경우, DB를 조회해서 객체를 영속 컨텍스트에 저장
DB에서 바로 삭제되는 것이 아니라, 영속성 컨텍스트(엔티티 매니저)에서만 제거되며, DELETE 쿼리를 쓰기 지연 SQL 저장소에 저장
em.remove()를 실행했을 때, 캐시에 등록되어 있던 엔티티가 삭제
delete 쿼리문을 쓰기 지연 SQL 저장소에 저장
트랜잭션 커밋 시 SQL 등록된 쿼리 전송하여 DB에서 삭제