[JPA] 플러시 ( flush )

윤들윤들·2020년 12월 21일
0
post-thumbnail

플러시 (flush)


이번에는 JPA 에서 flush가 무엇인지에 대한 내용에 대해 포스팅하고자 한다.

flush는 영속성 컨텍스트의 변경된 내용을 데이터베이스에 반영하기 위해 사용한다.

플러시(flush)를 실행하면 다음과 같은 일이 일어난다.

  1. JPA의 변경 감지가 동작하여 영속성 컨텍스트에 있는 모든 Entity를 스냅샷과 비교하여 변경된 Entity를 찾는다. 수정된 Entity는 수정 쿼리를 만들어서 쓰기 지연소에 저장한다.

  2. 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송한다. ( 등록, 수정, 삭제 )

위의 두가지 방법으로 flush가 동작합니다.


그렇다면 flush를 하는 방법은 어떤것들이 있을까??

■ 직접 호출
EntityManager의 flush()메서드를 직접 호출하여 강제로 플러시 한다.
테스트나 다른 프레임워크와 JPA를 같이 사용하지 않는이상 거의 사용하지 않는다.

■ 트랜잭션 커밋 시 플러시 자동 호출
트랜잭션만 커밋하게 된다면 데이터베이스에 변경사항이 반영되지 않는다.
따라서 트랜잭션을 커밋하기 전에 반드시 플러시를 호출해서 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영해야 한다. JPA는 이런 문제를 예방하기 위해 커밋할때 플러시를 자동으로 호출해 준다.

■ JPQL 쿼리 실행시 플러시 자동 호출
JQPL이나 Criteria 같은 객체지향쿼리를 호출할 때도 플러시가 실행된다.
호출되는 이유는 다음 예제에서 확인할 수 있다.

entityManager.persist(member1);
entityManager.persist(member2);
entityManager.persist(member3);

query = entityManager.createQuery("SELECT m FROM Member m", Member.class);

위 코드를 보고 생각해보도록 하겠습니다. 위의 코드를 실행하였을 경우 entityManager.createQuery 를 통해 SELECT를 하였을 경우 현재 flush 또는 트랜잭션이 끝나지 않아. 실제 데이터베이스에 member1, member2, member3이 조회되지 않을 거라고 생각합니다. 하지만 JPA 같은 경우에 이런 문제를 사전에 방지하기 위해 JPQL을 실행할 때 플러시를 자동으로 호출하게 한다. 따라서 위의 코드를 실행하였을때는 member1, member2, member3 에 대한 결과가 포함된다.
주의해야할 점은 find()를 하였을때는 flush가 실행되지 않는다.


:) 플러시 모드 옵션

만약 플러시를 기본 옵션이 아니라 커밋할 때만 플러시가 동작하게 하고 싶다면 플러스 모드 옵션을 이용하면된다 . 플러시 모드 옵션에는 2가지 모드가 있다

FlushModeType.AUTO - 커밋이나 쿼리를 실행할 때 플러시 ( default )
FlushModeType.COMMIT - 커밋할 때만 플러시


플러시 내용을 다루면서 주의해야할 사항은 다음과 같다 .

플러시를 호출하였다고 영속성 컨텍스트에 있는 내용들을 지운다고 생각하면 안된다. 영속성 컨텍스트의 변경 내용을 데이터베이스에 동기화하는 것이지. 플러시를 호출하였으니 데이터베이스에 변경내용을 전송하고 영속성 컨텍스트를 비운다는 개념이 아닙니다.

이처럼 내가 원하는 지점에 동기화를 늦추는것이 가능한 이유는 트랜잭션이 존재하기 때문이다.

profile
Front&BaackEnd를 재미있게 공부하고싶은 개발자 YundleYundle

0개의 댓글