JPA flush, commit

Kevin·2024년 3월 14일
2

JPA

목록 보기
12/14
post-thumbnail

서론

flush()도 현재 영속 컨텍스트에 있는 엔티티를 DB에 저장하고, commit()도 현재 영속 컨텍스트에 있는 엔티티를 DB에 저장하지않나? 이 둘은 뭐가 다른거지?

한번 이 둘의 차이점에 대해서 알아보자.


flush란?

	@Transactional
	@Override
	public void flush() {
		entityManager.flush();
	}

flush는 영속성 컨텍스트의 변경 내용을 DB에 반영하는 것을 말한다.

저번 글에서 잠깐 다뤘었던 쓰기 지연 저장소에 쌓여있던 Insert, Update, Delete SQL들이 flush()시에 DB에 날라간다.

이 때 명시를 해야할 것은 flush는 영속성 컨텍스트를 비우는 것이 아니라 영속성 컨텍스트와 DB의 상태를 맞추는 작업이다.

flush는 영속성 컨텍스트를 비우는 것이 아니라 영속성 컨텍스트와 DB의 상태를 맞추는 작업이다.

단 Commit 시에는 실제 DB에 반영 후 영속 컨텍스트를 비운다.

flush는 commit시 쓰기 지연 SQL 저장소에 등록된 쿼리를 DB로 전송한다.


또한 변경 감지(Dirty Checking)시에는 아래와 같이 동작한다.

  1. JPA에서 commit 할 시점에 flush()를 호출한다.
  2. JPA는 1차 캐시에 저장된 엔티티(commit 할 시점의 Entity의 변경 된 최종 상태)와 스냅샷을 비교한다.
    • 맨 처음 1차 캐시에 Entity가 저장될 때 그 상태를 복사해서 스냅샷으로 같이 저장한다.
  3. 변경이 감지되면, JPA는 UPDATE 쿼리를 쓰기 지연 SQL 저장소에 저장한다.
  4. flush를 통해서 쓰기 지연 SQL 저장소의 Query를 DB에 전송한다.
  5. commit된다.

일단 flush와 flush()의 차이를 알 필요가 있다.

간략하게 이야기하면 flush는 쓰기 지연 저장소에 등록된 쿼리를 DB에 전송하는 것을 의미한다.
그리고 flush()는 Entity와 스냅샷 비교, 비교 후 UPDATE를 쓰기 지연 SQL 저장소에 등록, 그리고 flush까지 포함하는 과정을 일컫는다.

즉 flush는 flush()의 한 과정이다.

flush는 또한 롤백이 가능하다.

롤백이 가능한 이유는 아직 commit이 이루어지지 않았기 때문이다.

그렇다면 commit은 무엇일까?

commit

commit은 트랜잭션의 모든 변경 내용을 데이터베이스에 영구적으로 반영한다.

commit은 내부적으로 flush를 수행한 후 트랜잭션을 끝내는 역할이다.

그렇기에 commit은 롤백이 불가능하다.

flush는 물품 구매(환불이 가능한)이고, commit은 최종 구매 확정(환불이 불가능 한)이다.

@Transactional 어노테이션안에서 일어나는 쿼리들 중 한개라도 실패하면, rollback을 수행하고 모든 쿼리들이 성공하면 해당 쿼리들을 모두 commit한다.


결론

JPA를 이해할 때 영속 흐름만 파악하면, 절반은 가는 것 같다.

영속 개념에 대해서 더 깊게 공부하자.

profile
Hello, World! \n

0개의 댓글