Back-End/JPA

JPA - 플러시(강제 쿼리 실행)

LightSource 2022. 7. 5. 20:07

플러시란?

  • 영속성 컨텍스트의 변경 내용을 DB에 반영하는 것
  • 보통 트랜잭션이 커밋이 될때, 플러시가 발생한다.
  • 영속성 컨텍스트의 변경사항과 DB를 동일하게 맞추는 작업

플러시의 동작 과정

  1. 변경 감지
  2. 수정된 Entity를 쓰기 지연 SQL 저장소에 등록
  3. 쓰기 지연 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에 동기화
  • 트랜잭션이라는 작업 단위가 중요 → 커밋 직전에만 동기화 하면 된다.
반응형