플러시란?
- 영속성 컨텍스트의 변경 내용을 DB에 반영하는 것
- 보통 트랜잭션이 커밋이 될때, 플러시가 발생한다.
- 영속성 컨텍스트의 변경사항과 DB를 동일하게 맞추는 작업
플러시의 동작 과정
- 변경 감지
- 수정된 Entity를 쓰기 지연 SQL 저장소에 등록
- 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송 (등록, 수정 삭제 쿼리)
- 플러시가 발생한다고 해서 commit이 발생하지는 않고, 플러시 이후 실제 commit이 일어난다.
- 플러시가 동작할 수 있는 이유는 데이터베이스 트랜잭션 때문이다.
→ 데이터베이스는 트랜잭션이 시작되고, 해당 트랜잭션이 commit이 되는 시점 이전에 동기화 해주면 되기때문
영속성 컨텍스트가 플러쉬 되는 상황
1. em.flush() 직접호출
Member member = new Member(200L, "member200");
em.persist(member);
em.flush(); // 강제로 플러시를 호출해서 DB에 반영
System.out.println("=========================");
tx.commit(); // [트랜잭션] 커밋
em.flush()
를 사용하면, 커밋을 하지않아도 강제로 쿼리문을 실행 한다.- 플러시가 일어나도 1차캐시에 데이터는 그대로 남아 있다.
- 플러시는 쓰기 지연 SQL저장소에 있는 쿼리를 DB에 실행하는 과정이다.
2. 트랜잭션 커밋 시 플러시 자동 호출
3. JPQL 쿼리 실행 시 플러시 자동 호출
em.persist(memberA);
em.persist(memberB);
em.persist(memberC); //member A, B, C를 영속성 컨텍스트에 저장
//중간에 JPQL 실행 -> member A,B,C를 조회하기위해 flush() 를 실행후, JPQL 실행
query = em.createQuery("select m from Member m", Member.class);
List<Member> members= query.getResultList();
- 위에서 memberA, B, C를 영속성 컨텍스트에 저장한 상태에서 DB에 Member테이블을 조회시 아직 insert쿼리문이 실행이 안되었기 때문에 memberA, B, C의 값이 조회되지 않으므로, 이를 방지하기위해 JPA는 자동으로 JPQL 쿼리 실행시
flush()
를 자동으로 실행 한다.
플러시 모드 옵션
FlushModeType.AUTO
커밋이나 쿼리를 실행할 때 플러시 (기본값)FlushModeType.COMMIT
커밋할 때만 플러시
플러시 정리
- 영속성 컨텍스트를 비우지 않는다.
- 영속성 컨텍스트의 변경내용을 DB에 동기화
- 트랜잭션이라는 작업 단위가 중요 → 커밋 직전에만 동기화 하면 된다.
반응형