본문 바로가기

Spring/JPA & Hibernate

플러시

반응형

플러시 란?

영속성 컨텍스트의 변경내용이 데이터베이스에 반영되는 것

  • 변경 감지
  • 수정된 엔티티를 쓰기 지연 SQL 저장소에 등록
  • 쓰지 지연 SQL 저장소의 쿼리(등록, 수정, 삭제 쿼리)를 데이터베이스에 전송 
플러시가 발생한다고해서 데이터베이스 트랜잭션이 커밋되는 것은 아님, 데이터베이스에 반여이되고, transaction.commit() 시 커밋 됨
또한, 영속성 컨텍스트의 쓰기 지연 SQL 쿼리들이 데이터베이스에 반영될 뿐, 1차 캐시의 내용이 삭제되는 것은 아님.

영속성 컨텍스트를 플러시하는 방법

  1. em.flush() 로 직접 호출할 수 있다.
  2. 트랜잭션 커밋하면 플러시가 자동으로 호출된다.
  3. JPQL 쿼리 실행시 플러시가 자동으로 호출된다

Member member = new Member( 200L, "member200" );
em.persist( member );

// 쓰기 지연 SQL 저장소의 쿼리들이 db에 반영됨
em.flush();

System.out.println( "=========" );

// database 저장
tx.commit();

실행 결과

실행 결과에서 볼 수 있듯이, "==========" 이 출력되기 전에 쿼리가 실행된 것을 확인할 수 있다.

즉, 커밋 시점이 아닌 플러시 시점에 쿼리가 실행된 것이다.

 

JPQL 쿼리 실행시 플러시가 자동으로 호출되는 이유

JPQL의 경우, 영속성 컨택스트에 적용되는 것이 아니라, 데이터베이스에 직접 쿼리를 실행하는 것이기 때문에

JPQL로 쿼리 실행 직전에 영속성 컨택스트의 내용(같은 트랜잭션에서 이전에 발생한 쿼리)을 데이터베이스에 반영을 해줘야한다.


Member memberA = new Member( 241L, "memberA" );
Member memberB = new Member( 242L, "memberB" );
Member memberC = new Member( 243L, "memberC" );

em.persist( memberA );
em.persist( memberB );
em.persist( memberC );

System.out.println( "=====================" );

//중간에 JPQL 실행
TypedQuery<Member> query = em.createQuery( "select m from Member m", Member.class );
System.out.println( "=====================" );

// 조회
List<Member> members = query.getResultList();
System.out.println( "=====================" );

// database 저장
tx.commit();

실행 결과

위 코드와 실행 결과를 보면, JPQL 조회 쿼리 실행 직전에 모든 INSERT 쿼리가 실행되는 것을 볼 수 있다. memberA. memberB, memberC 는 DB에 반영되지 않았고, 일차 캐시에만 반영이 되어있기 때문에, 쿼리를 실행하지 않고서는 SELETE Query를 통해 데이터베이스에서 엔티티를 가져올 수 없다.

이러한 문제를 방지하기 위해 JPA에서는 JPQL 실행 시에 플러시를 자동으로 호출하여 쓰기 지연 SQL 저장소에 있는 쿼리들을 데이터베이스에 반영한다.

플러시 모드 옵션

  • FlushModeType.AUTO

    커밋이나 쿼리를 실행할 때 플러시 (기본값) 
  • FlushModeType.COMMIT

    커밋할 때만 플러시
    쿼리를 실행할 때는 플러시를 하지 않는다.
    내가 생성한 쿼리에서 참조하는 데이터를 동일 트랜잭션의 이전 코드에서 변경하지 않았다면, 굳이 이전 내역을 데이터베이스에 반영필요가 없기 때문에 사용할 수 있음.

 

플러시 모드를 변경할 수 있다.
em.setFlushMode(FlushModeType.COMMIT)

플러시 

  • 영속성 컨텍스트를 비우지 않는다.
  • 영속성 컨텍스트의 변경내용을 데이터베이스에 동기화하는 것
  • 플러시가 존재할 수 있는 이유는 데이터베이스 트랜잭션이라는 개념이 있기 때문이다.
    즉, 트랜잭션 작업 단위가 중요 -> 커밋 직전에만 동기화 하면 됨

 

반응형

'Spring > JPA & Hibernate' 카테고리의 다른 글

Entity Mapping  (0) 2019.12.19
준영속 상태  (0) 2019.12.18
영속성 컨텍스트  (0) 2019.12.18
JPA Example  (0) 2019.12.18
h2 database 사용하기  (0) 2019.12.17