"인프런 - 자바 ORM 표준 JPA 프로그래밍 강의를 듣고 작성한 글 입니다."
www.inflearn.com/course/ORM-JPA-Basic#
자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런
JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들이 JPA의 기본 이론을 탄탄하게 학습해서 초보자도 실무에서 자신있게 JPA를 사용할 수 있습니다. 초급 웹 개발 프로그
www.inflearn.com

이번엔 앞서 작성한 영속성 컨텍스트 포스팅에서 언급했던 플러시(flush) 에 대해서 알아보자.
"플러시(flush)" 란 영속성 컨텍스트의 변경내용을 데이터베이스에 반영해주는 것이다.
- 보통 데이터베이스 트랜잭션이 커밋될 때 일어난다.
- 쌓아두었던 SQL 쿼리들이 데이터베이스에 전달되는것, 즉 영속성 컨텍스트의 변경사항과 데이터베이스를 일치시키는 작업이다.
- 영속성 컨텍스트의 쿼리들을 데이터베이스에 전달한다.
* 플러시(flush) 가 발생하는 경우 예시
- 변경 감지(Dirty Checking) -> 수정된 entity 에 대한 쿼리가 쓰기 지연 SQL 저장소에 전송 -> 쓰기 지연 SQL 저장소의 쿼리를 데이터베이스에 전송하기 위한 트랜잭션 커밋
위의 과정에서 도달할 수 있는 결론은 바로 데이터베이스 트랜잭션이 커밋된다고 해서 반드시 플러시가 발생하는 것이 아니라 entity 의 데이터 수정이 발생하면 변경 감지기능이 수행된 이후, 데이터베이스 트랜잭션 커밋 시점에 flush 를 발생 시킴으로서 쓰기 지연 SQL 저장소에 쌓여있던 쿼리들이 데이터베이스에 전달되는 것이다.
그렇다면 flush 가 발생하였을 경우 1차 캐시에 있는 내용은 어떻게 될까?
-> 지워지지 않고 유지 된다. (flush 는 영속성 컨텍스트의 쓰기 지연 SQL 저장소에 있는 쿼리들이 데이터베이스에 반영되는 과정이다.)
* 그렇다면 영속성 컨텍스트를 어떻게 flush 할 수 있을까?
1. 직접 호출한다 - em.flush();
-> 거의 쓸일은 없으나 테스트의 경우 알아두면 좋다.
2. 플러시 자동 호출 - 데이터베이스 트랜잭션 커밋, JPQL 쿼리 실행
* JPQL 쿼리 실행 시 플러시가 자동으로 호출되는 이유?
em.persist(memberA);
em.persist(memberB);
em.persist(memberC);
// 중간에 JPQL 실행
query = em.createQuery("select m from Memeber m", Member.class);
List<Member> members = query.getResultList();
persist 를 실행하여 영속성 컨텍스트에 객체 데이터를 올려놓은 이후, JPQL 쿼리를 이용해 해당 데이터를 조회하려고 하면, 아직 데이터베이스에 쿼리가 전달되어 데이터가 저장된 상황이 아니기 때문에 기본적으로 조회가 되지 않는게 원칙이다.
그런데 위와 같은 이유로 인해 여러가지 문제가 발생할 수 있다.(아직 데이터베이스에 저장되지 않은 entity 를 조회해야 할 경우 문제가 발생할 수 있다.)
그렇기 때문에 JPA 는 JPQL 을 통한 쿼리가 발생한 경우 일단 무조건 자동으로 flush() 를 실행하는 기능을 갖췄다.
(JPQL 쿼리가 발생된 경우 일단 무조건 flush 를 발생시킨 후 해당 쿼리를 데이터베이스로 전달한다.)
* 플러시 모드 옵션
거의 쓸일은 없으나 이런게 있다는 정도만 알고 넘어가자
em.setFlushMode(FlushModeType.AUTO);
em.setFlushMode(FlushModeType.COMMIT);
FlushModeType.AUTO : 커밋이나 쿼리를 실행할 때 플러시(기본값)
-> 내가 트랜잭션을 커밋하거나 쿼리를 실행할 때, 플러시를 한 후에 커밋을 하거나, 플러시를 한 후에 쿼리를 실행하는것
FlushModeType.COMMIT : 커밋할 때만 플러시(쿼리를 실행할 때는 플러시를 하지 않는다.)
-> 해당 옵션이 도움이 되는 경우?
: JPQL 을 통한 쿼리를 실행 할 때, 해당 트랜잭션을 통해 변경된 데이터가 있는 테이블이 아닌 다른 테이블의 데이터를 불러올 경우. 즉, 데이터의 변경이 일어나지 않아 해당 테이블의 데이터에 커밋이 필요하지 않은 경우(쿼리의 전달만 이루어진 경우) // 강사님 말씀으로는 사실 별 도움은 안되니 가급적 이 옵션은 손대지 말고 그냥 AUTO 로 쓰자고 하셨다.
*정리!
- 플러시(flush) 는 영속성 컨텍스트를 지우는 것이 아니다!
- 플러시(flush) 는 영속성 컨텍스트의 변경내용을 데이터베이스에 동기화하는 작업이다.
- 플러시(flush) 의 매커니즘이 동작할 수 있는 이유는 사실 트랜잭션 이라는 작업단위가 있기 때문이다.
-> 커밋 직전에만 동기화 하면 된다.(쿼리를 데이터베이스에 전달해주면 됨)
JPA 는 기본적으로 데이터를 맞추는 등의 동시성에 대한 경우는 다 데이터베이스 트랜잭션에 위임해서 사용한다.
'JPA' 카테고리의 다른 글
| 객체와 테이블 간 Entity 매핑 (0) | 2020.09.19 |
|---|---|
| 준영속 상태에 대하여.... (0) | 2020.09.12 |
| 영속성 컨텍스트의 이점 - 변경 감지, 엔티티 삭제 (0) | 2020.09.09 |
| 영속성 컨텍스트의 이점 - 동일성 비교와 트랜잭션 쓰기 지연 (0) | 2020.09.09 |
| 영속성 컨텍스트의 이점 - 1차 캐시 (0) | 2020.09.09 |