본 포스팅은 인프러의 JPA 기본편을 수강하고 정리하는 내용입니다.
영속성 컨텍스트의 변경내용을 데이터베이스에 반영하는 것이 플러시
이다. 즉, 영속성 컨텍스트의 변경사항과 실제 DB를 맞춰주는 것이다.
플러시 발생
- 변경 감지
- 수정된 엔티티 쓰기 지연 SQL 저장소에 등록
- 쓰기 지연 SQL 저장소의 쿼리를 DB에 전송
- (등록, 수정, 삭제 쿼리)
영속성 컨텍스트를 플러시하는 방법
em.flush()
- 직접 호출트랜잭션 커밋
- 플러시 자동 호출JPQL 쿼리 실행
- 플러시 자동 호출
flush() 를 호출해도 1차 캐시에 있는 데이터를 지우는게 아니다. 오직 쓰기 지연 SQL 저장소
에 있는 쿼리들만 DB에 반영되는 과정이다.
JPQL 쿼리 실행시 플러시가 자동으로 호출되는 이유
1
2
3
4
5
6
7
em.persist(memberA);
em.persist(memberB);
em.persist(memberC);
//중간에 JPQL 실행
query = em.createQuery("select m from Member m", Member.class);
List<Member> members= query.getResultList();
실제 JPQL이 실행되기전에 memberA, memberB, memberC가 DB에 저장되지 않는다면 JPQL이 실행될때 실제 sql쿼리가 생성되고 호출되는데 실제 DB에 가져올게 없기에 잘못하면 문제가 생길 수 있다. 그래서 JPA는 이러한 문제를 방지하고자 JPQL 쿼리 실행시 플러시가 자동으로 호출되도록 하였다.
플러시 모드 옵션
1
em.setFlushMode(FlushModeType.COMMIT)
FlushModeType.AUTO
- 커밋이나 쿼리를 실행할 때 플러시 (기본값)
FlushModeType.COMMIT
- 커밋할 때만 플러시 => JPQL 실행 시 플러시 할 필요가 없다면 COMMIT모드로 바꿔도 된다
굳이 손대지 않고 AUTO로 써도 된다.
플러시는!
- 영속성 컨텍스트를 비우지 않음
- 영속성 컨텍스트의 변경내용을 데이터베이스에 동기화
- 트랜잭션이라는 작업 단위가 중요 ->
커밋 직전에만 동기화하면 됨
JPA는 기본적으로 데이터를 맞추거나 동시성에 대한건 데이터베이스 트랜잭션에 위임해서 이뤄진다.