본문 바로가기
Framework/🍃Spring

JPA - 플러시(Flush)란?

by 발개발자 2022. 12. 1.
반응형

JPA의 flush에 대해 알아보자.

플러시란 영속성 컨텍스트의 변경내용을 데이터베이스에 반영하는 작업

 

 

  Flush의 원리

보통 트랜잭션 Commit이 발생할때, flush가 동작한다.

이때, 쓰기지연 SQL저장소에 등록된 insert, update, delete query들이 전송된다.

여기서 중요한 점이, flush가 발생한 시점에 영속성 컨텍스트를 비우는게 아니라, 그대로 유지한채로 DB와 동기화를 하는 것이다. 

따라서, 트랜잭션이라는 작업단위가 중요해지고 Commit직전에만 동기화하면 된다.

 

 

  Flush의 동작 구조

  • 변경 감지 (Dirty Checking)
  • 수정된 엔티티를 쓰기 지연 SQL 저장소에 등록
  • 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송(등록, 수정, 삭제 query)

 

 

  Flush를 호출하는 방법

1. EntityManager의 flush 직접 호출

EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();

try{
    Member member = new Member(200L, "member200");
    em.persist(member);
    
    em.flush(); // flush 호출!!
    
    tx.commit();
}

위의 코드를 보면 em.flush()를 하는 시점에서 query가 전송되고 Commit하는 시점에 반영된다.

즉, flush를 한다고 DB에 즉시 반영되는 것이 아니다. Commit을 해야 DB 반영이 된다.

 

 

 

 

2. 트랜잭션 커밋

EntityManager em = emf.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();

try{
    Member member = new Member(200L, "member200");
    em.persist(member);
    
    tx.commit(); // flush 호출
}

기본적으로, flush는 트랜잭션을 Commit 하는 시점에 자동으로 호출된다.

 

 

 

3. JPQL 쿼리 실행

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을 실행했을때에도 flush가 호출된다. 

왜 why 호출될까?

 

위의 소스를 보면 persist를 하는 시점에는 DB에 query가 전송되지 않는다.

여기서 JPQL을 호출했을 때, 아무것도 조회를 못하는 문제가 발생할 수 있다.

따라서, JPA는 JPQL을 실행하였을 때 쓰기지연저장소의 query들을 전부 전송(flush)하고 JPQL을 날려서 안전성을 보장하게 된다.

 

 

 

  Flush 옵션

FlushModeType.AUTO

기본 설정 값으로, 트랜잭션을 Commit하거나 JPQL과 같은 Query를 실행할 때 flush를 먼저 수행한다.

 

FlushModeType.COMMIT

트랜잭션을 Commit할 때만 flush를 호출한다.

JPQL에서 flush와 영향없는 테이블을 조회할 때는 flush로 얻을 수 있는 이점이 없기때문에,

해당 모드를 사용할 수 있지만, 대체로 AUTO를 권장한다.

 

 

 

본 내용은 아래의 강의를 참고했습니다.

https://www.inflearn.com/course/ORM-JPA-Basic

반응형

댓글