본문 바로가기
Develop/JPA

[JPA/기본편] 플러시

by J-rain 2024. 3. 20.

플러시

플러시는 영속성 컨텍스트의 변경 내용을 데이터베이스에 반영한다.

플러시를 수행하면 구체적으로 아래의 일이 일어난다.

 

플러시 수행 과정

  1. 변경 감지가 동작해서 영속성 컨텍스트에 있는 모든 엔티티를 스냅샷과 비교한다.
  2. 수정된 엔티티가 있다면 수정 쿼리를 만들어 쓰기 지연 SQL 저장소에 등록한다.
  3. 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송한다.
  4. (등록, 수정, 삭제 쿼리가 저장된다. 조회 쿼리는 저장되지 않고 바로바로 수행한다.)

 

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

영속성 컨텍스트를 플러시하는 방법은 아래 3가지이다.

  •  em.flush()  직접 호출한다.
  • 트랜잭션 커밋 시 플러시가 자동 호출된다.
  • JPQL 쿼리 실행 시 플러시가 자동 호출된다.

 

직접 호출

엔티티 매니저의 flush() 메소드를 직접 호출해서 영속성 컨텍스트를 강제로 플러시한다.

특수한 상황을 제외하고는 거의 사용하지 않는다.

(특수한 상황에는 테스트 또는 다른 프레임워크와 JPA를 사용하는 상황이 있다.)

flush()를 수행해도 1차 캐시의 데이터는 지워지지 않는다.

 

 

트랜잭션 커밋 시 플러스 자동 호출

커밋은 데이터베이스에 작업 내용을 반영하는 것이고 플러시는 SQL을 데이터베이스로 전달하는 것이다.

따라서 커밋전 플러시를 하지 않으면 어떠한 데이터의 추가, 수정, 삭제도 반영되지 않는다.

JPA는 이런 문제를 예방하기 위해 트랜잭션을 커밋할 때 플러시를 자동으로 호출한다.

 

JPQL 쿼리 실행 시 플러시 자동 호출

JPQL이나 Criteria 같은 객체지향 쿼리를 호출할 때도 플러시가 실행된다.

이유는 아래의 예를 통해 알아보자.

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();

 

먼저  em.persist()  를 호출해서 엔티티 memberA, memberB, memberC를 영속 상태로 만들었다.

하지만 데이터베이스에 반영되지는 않았다.

이때 JPQL을 실행하면 memberA, memberB, memberC는 아직 데이터베이스에 없기때문에 쿼리 결과로 조회되지 않는다.

따라서 JPA는 이런 문제를 예방하기 위해 JPQL을 실행할 때도 플러시를 자동 호출한다.

참고

식별자를 기준으로 조회하는 find() 메소드를 호출할 때는 플러시가 실행되지 않는다.

 

플러시 모드 옵션

가급적 플러시 모드는 기본값 사용을 권장한다.

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

코드

em.setFlushMode(FlushModeType.COMMIT) //플러시 모드 직접 설정

'Develop > JPA' 카테고리의 다른 글

[JPA/기본편] 연관관계  (1) 2024.03.20
[JPA/기본편] 엔티티 매핑  (0) 2024.03.20
[JPA/기본편] 준영속 상태  (0) 2024.03.20
[JPA/기본편] 영속성 컨텍스트  (0) 2024.03.20
[JPA/기본편] JPA  (0) 2024.03.19

댓글