# flush()

flush()

1. 영속성 컨텍스트를 비우지 않고, 영속성 컨텍스트의 변경내용을 DB에 동기화\
   flush()를 한다고 1차 캐시 내용이 다 없어지는 건 아니다! \
   변경된 사항들이 DB에 반영되는 것이다.
2. **트랜잭션**이라는 작업 단위가 중요하다! -> 커밋 직전에만 동기화 하면 됨
3. **JPA는 데이터를 일관성있게 유지하고 동시성에 관련한 것은 트랜잭션에 위임한다.**
4. **영속성 컨텍스트와 트랜잭션 주기가 맞게 설계해야 데이터 동기화에 문제가 없다.**

flush()가 발생할 때 일어나는 일들

1. 변경 감지
2. **수정된 엔티티 쓰기 지연 SQL 저장소에 등록**
3. 쓰기 지연 SQL 저장소의 **쿼리를 데이터베이스에 전송**\
   (등록, 수정, 삭제 쿼리)

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

1. em.flush() - 직접 호출 (스프링부트\&JPA가 자동화해주어서 실제 애플리케이션 개발에 잘 사용하지는 않는 것 같음)
2. 트랜잭션 커밋 - 플러시 자동 호출
3. **JPQL 쿼리 실행 - 플러시 자동 호출**\
   **=>persist만 하고(영속성 컨텍스트에 등록만 하고) 테이블에서 데이터를 조회하는 JPQL을 작성하면 실제로 DB에서 데이터를 가져와야하기 때문에 이 때는 플러시가 자동 호출된다!!**

```java
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.setFlushMode(FlushModeTypee.COMMIT)

* FlushModeType.AUTO : 커밋이나 쿼리 실행할 때 플러시 (기본값)
* FlushModeType.COMMIT : 커밋할 때만 플러시\
  현재 persist하는 테이블과 다른 테이블을 조회할 때는 굳이 플러시하지 않아도 되기 때문에 커밋할 때만 플러시하는 것으로 설정 가능(비추천)<br>
