플러시(flush)는 영속성 컨텍스트의 변경내용을 데이터베이스에 반영하는 것을 말한다. 플러시가 발생하면 다음과 같은 일이 발생되게 된다.
- 변경 감지가 동작하여 영속성 컨텍스트에 있는 모든 엔티티의 스냅샷과 비교하여 수정된 엔티티를 찾는다. 수정된 엔티티는 수정 쿼리를 만들어 쓰기 지연 SQL 저장소에 등록한다.
- 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송한다. (등록, 수정, 삭제 쿼리)
영속성 컨텍스트를 플러시 하는 방법
직접호출
엔티티 매니저의 flush() 메소드를 직접 호출해서 영속성 컨텍스트를 강제로 플러시한다. 테스트나 다른 프레임워크와 JPA를 함께 쓰는 경우를 제외하고 거의 사용되지 않는다.
트랜잭션 커밋 시 플러시 자동 호출
트랜잭션을 커밋하지 않으면 데이터베이스에 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> member = query.getResultList();
위 코드를 보면 알겠지만 persist 하는 것만으로 데이터베이스에 반영이 되지 않는다. 반영되지 않은 상태에서 JPQL를 이용해 SQL 조회를 하면 문제가 발생되게 된다. 그렇기때문에 JPQL 실행 전 플러시가 동작하게 된다.
참고로 식별자를 기준으로 조회하는 find() 메서드를 호출할 때는 플러시가 실행되지 않는다.
find()는 영속성 컨텍스트 내부 검색하여 이미 존재한다면, 플러시가 실행될 필요가 없다.
위 코드에서는 이미 perisist() 메서드 실행 순간 이미 영속성 컨텍스트에 기록이 된다.
플러시 모드 옵션
엔티티 매니저에 플러시 모드를 직접 지정할 수 있다.
FlushModeType.AUTO : 커밋이나 쿼리를 실행할 때 플러시(기본값)
FlushModeType.COMMIT : 커밋할 때만 플러시
플러시 모드를 따로 지정하지 않으면 AUTO로 동작한다. 대부분 AUTO를 사용하고 성능 최적화를 위해 COMMIT를 변경하여 사용하는 경우도 있지만 잘 사용되지는 않는다.
참고로
플러시라는 이름때문에 실행 시 영속성 컨텍스트에 보관된 엔티티를 지운다고 생각할 수 있으나 그렇지 않다. (영속성 컨텍스트 1차 캐시를 비운다 등..)
플러스는 영속성 컨텍스트의 변경 내용을 데이터베이스에 동기화하는 것을 의미한다.
참조
김영한님 강의 [자바 ORM 표준 JPA 프로그래밍 - 기본편] 참조
'Framework > JPA' 카테고리의 다른 글
[JPA] 엔티티 매핑 - 객체와 테이블 매핑 (0) | 2024.03.14 |
---|---|
[JPA] 준영속 상태 (0) | 2024.03.13 |
[JPA] 영속성 컨텍스트의 특징 (0) | 2024.03.12 |
[JPA] 영속성 컨텍스트 (0) | 2024.03.12 |
[JPA] JPA란? (0) | 2024.03.12 |