JPA

2-2. 플러시

희구 2021. 8. 2. 22:21

플러시

영속성 컨텍스트의 변경내용을 데이터베이스에 반영하는 것.

영속성 컨텍스트의 변경사항과 데이터베이스르 맞추는 작업

영속성 컨텍스트의 쿼리를 디비에 날려주는 것.

 

데이터베이스가 커밋되면 플러시가 자동으로 발생한다.

 

 

플러시가 발생하면?

  • 변경이 감지됨
  • 수정된 엔티티를 쓰기지연 SQL저장소에 등록한다
  • 쓰기지연 Sql저장소의 쿼리를 데이터베이스에 전송한다. (등록, 수정, 삭제 쿼리)

 

영속성 컨텍스트를 어떻게 플러시하는가?

  • em.flush()라고 직접 호출하기
  • 트랜잭션 커밋 - 자동 호출
  • JPQL 쿼리 호출 - 자동 호출

 

Member member = new Member(200L, "member200");
em.persist(member);

em.flush();//강제로 호출.

System.out.println("=================");

tx.commit(); /*커밋*/

커밋되기 전까진 member값이 영속성 컨텍스트에는 있지만 아직 데이터베이스에는 반영되지 않았다.

그렇기 때문에 이 쿼리를 볼 수 없다.

미리 디비에 반영하거나 미리 쿼리가 날라가는걸 보고싶다면

em.flush()로 강제호출을 한다.

 

그렇게 되면 쿼리결과에 포함된다.

 

image-20210802221450979

플러시를 해버리니까 "========" 이전, 그니까 커밋도 하기 전에 디비에 저장되어버린다.

 

flush()를 한다고 1차캐시가 지워지는 건 아니다.

오직 영속성 컨텍스트의 쓰기지연SQL저장소에 쌓여있는 쿼리들이 몽땅 데이터베이스에 반영되는 것 뿐.

 

 

 

JPQL쿼리 실행 시 플러시가 자동으로 호출되는 이유

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

memberA,B,C를 em.persist로 저장을 했다.

실제 데이터베이스에 이 쿼리가 날라가지 않는다.

 

넣은 다음 바로 아래 코드로 조회를 해온다. (em.createQuery("select m from Member m", Member.class))

그럼 조회가 될까 안될까?

조회가 안된다.

 

왜? 디비에 쿼리라도 날라가야 디비에서 가져올텐데

지금은 쿼리조차 실행되지 않았기 때문이다.

그래서 jpa는 이런걸 방지하기 위해 무조건 플러시를 날려버린다.(자동으로 플러쉬를 호출함)

 

 

 

 

플러시란?

• 영속성 컨텍스트를 비우지 않음

• 영속성 컨텍스트의 변경내용을 데이터베이스에 동기화

• 트랜잭션이라는 작업 단위가 중요 -> 커밋 직전에만 동기화 하면 됨

 

 

 

 

 

 

 

 

[출처] 김영한님의 자바 ORM 표준 JPA 프로그래밍 - 기본편

(https://www.inflearn.com/course/ORM-JPA-Basic/dashboard)