플러시는 영속성 컨텍스트의 변경 내용을 DB에 반영한다.
구체적으로 다음과 같은 일이 발생한다.
- 변경 감지가 동작해서 영속성 컨텍스트에 있는 모든 엔티티와 스냅샷을 비교하여 수정된 엔티티를 찾는다.
- 수정된 엔티티는 SQL을 만들어 저장소에 저장
- DB에 전송한다.
영속성 컨텍스트를 플러시하는 방법은 3가지 이다.
- 직접 em.flush() 를 호출
- 트랜잭션 커밋시 자동으로 호출
- JPQL 쿼리 실행시 자동으로 호출
- 직접 호출 방식은 테스트 또는 타 프레임워크와 JPA를 쓸 떄빼고 거의 미사용
- 커밋시 자동 호출하는 이유는 변경 내용을 DB에 전달하지 않고 커밋만 하면
내용의 변화가 없기 때문에 꼭 커밋전 호출해서 반영을 해야한다
이러한 문제를 방지하기 위해서 자동호출이 실행된다.
persist로 3개의 객체를 영속 상태로 만들었지만 DB에 반영되지 않은 상태에서
JPQL로 호출하면 결과가 조회되지 않는다.
JPQL은 DB를 조회해서 엔티티를 가져온다. 하지만 현재 영속상태인 3개의 객체는
DB에는 반영되지 않은 상태이기 때문에 플러시를 통해서 JPQL 실행 직전에
DB에 반영을 시켜둬야한다 그래서 자동호출이 발생한다.
find 메서드에는 플러시가 실행되지 않는다.
- 플러시 모드 옵션
EM 에 직접 플러시 모드를 지정하려면 FlushModeType을 사용하면 된다.
- FlushModeType.AUTO : 커밋이나 쿼리를 실행할 떄 플러시
- FlushModeType.COMMIT : 커밋시에만 플러시
별도로 지정하지 않으면 AUTO 방식으로 동작하여 커밋이나 쿼리실행시 플러시가 자동호출한다.
성능 최적화를 위해서 COMMIT 을 사용할 수 도 있다.
플러시가 영속성 컨텍스트의 엔티티를 지운다는것이 아니다.
컨텍스트 변경 내용을 DB에 동기화하는 것이 플러시이다.
동기화를 늦추는 이유는 트랜잭션이라는 작업단위가 있기 떄문이다
트랜잭션 커밋 직전에만 DB에 변경내용을 보내 동기화 하면 된다.
'Back-End > JPA' 카테고리의 다른 글
JPA) 병합 merge (0) | 2022.03.11 |
---|---|
JPA) 준영속 상태 (0) | 2022.03.11 |
JPA) 변경 감지 (Dirty Check) (0) | 2022.03.11 |
JPA) 영속성 컨텍스트 개념 및 특징 (0) | 2022.03.11 |
JPA) EM, EMF (0) | 2022.03.11 |