Skip to content

"플러시(flush) 알아보기"

Intro

저번 글에서 엔티티 객체를 영속성 컨텍스트(persistence context)에 영속시키는 과정들을 살펴봤다. 이번 글에서는 영속 상태에 놓인 객체들을 데이터 베이스(DB)에 저장해 보겠다.

flush

영속 상태의 엔티티 객체는 어떻게 DB에 저장될까? 바로 플러시(flush)를 호출함으로써 가능하다. 플러시는 트랜잭션 과정 중에 영속성 컨텍스트에 들어온 엔티티 객체들을 DB와 동기화(Create, Update, Delete) 시키는 역할을 한다. 이 과정은 커밋이 수행되는 시점에 쓰기 지연 저장소에 저장된 쿼리를 한 번에 DB 에 보내는 방식으로 진행된다.

트랜잭션이 커밋하면 자동으로 플러시가 호출된다. 대부분 이 방식으로 플러시를 쓴다. 직접 플러시를 호출하거나, 혹은 JPQL 쿼리를 실행하는 방식(이 때도 플러시가 자동호출됨)으로는 잘 사용하지 않는다.
트랜잭션을 통해 플러시를 사용해 보자. 트랜잭션은 엔티티매니저를 통해 얻을 수 있다. 엔티티매니저를 통해 얻은 트랜잭션 <엔티티매니저를 통해 얻은 트랜잭션>

트랜잭션 사용 유무에 따라 플러시가 되는지 안 되는지 확인해 보겠다. 트랜잭션이 사용된 메서드와 사용되지 않은 메서드를 나눠서 진행해 보았다.

withTransaction noTransaction
<트랜잭션 유무에 따라 나눈 메서드>

먼저 noTransaction() 메서드를 호출했지만, SQL은 실행되지 않았고, DB에도 역시 저장되지 않았다. 그럼 이제 withTransaction() 메서드를 호출하자.

sql 2번 db 데이터 2개

전과 다르게 트랜잭션의 커밋이 끝나는 시점에 쿼리가 날라가는 것을 볼 수 있다. 이때 noTransaction 메서드에서 영속시킨 엔티티 객체도 함께 플러시된다. 이 과정은 커밋이 수행되는 시점에 쓰기 지연 저장소에 저장된 쿼리를 한 번에 DB 에 보내는 방식으로 진행된다.

위에 처럼 매번 트랜잭션의 시작과 커밋을 코드로 구현하기엔 번거로울 때도 있다. 그럴때는 @Transactional 어노테이션을 사용하면 간편하다. @Transactional 어노테이션을 사용하면 트랜잭션의 시작(begin)과 커밋(commit)을 자동으로 수행해준다. 트랜잭션의 시작은 메서드가 시작되기 전에 시작되고, 커밋은 메서드가 종료된 후에 커밋된다. 물론 커밋이 되기 전에 예외가 발생하면 롤백(rollback)된다.

마치며

영속 상태에 놓인 객체는 플러시를 통해 데이터베이스에 저장되고 대부분의 이 과정은 트랜잭션과 함께 진행된다. 다음 글에서는 트랜잭션의 범위와 동시성 문제에 대해 살펴보겠다.


작성자: 김민철

작성일: 2022-01-10