JPA 트랜잭션 내에서 엔티티를 변경할 때 마다 flush 해야하나요?

주싱·2023년 4월 13일
0

Data transfer icons created by juicy_fish - Flaticon

JPA 영속성 관리에 대해 공부했다. 예전에 팀에서 백엔드 엔지니어(DB를 다루는)들이 모여서 이것과 관련해서 옥신각신 하던 일이 생각났다. 그때 회사 코드에서 하나의 트랜잭션 내에서 엔티티를 변경할 때 마다 flush를 하고 있었는데 영희(가칭)가 매번 flush를 할 필요가 없다고 의견을 주었다. 그때 내 파트가 아니라서 잘 이해하지 못하고 그냥 듣고만 있었는데 어제 공부한 내용이 딱 그 내용인 것 같다.

커밋할 때 자동으로 flush 된다

그때 영희의 의견은 이랬다. 변경을 최종 커밋할 때 내부적으로 flush가 자동으로 일어나기 때문에 한 트랜잭션 내에서 엔티티를 변경할 때마다 flush하는 건 불필요하고 오히려 성능에 좋지 않을 수 있다고 했다. 작은 것들을 모아서 한 번에 처리하여 성능을 높이는 전략같다. 아직 잘 모르지만 꼭 필요할 때 까지(커밋 시점) 처리를 지연함으로 어떤 최적화를 JPA가 수행하지 않을지 상상해 본다. 실제로 어제 공부한 내용에 따르면 한 트랜잭션 내에서 매번 flush를 하더라도 어짜피 커밋이 되어야 DB 테이블에 반영되기 때문에 변경을 모았다가 커밋 전에 한꺼번에 flush 하는 것과 결과가 같다고 했다.

쿼리를 보낼 때 자동으로 flush 된다

그때 철수(가칭)가 트랜잭션 내에서 변경 된 엔티티(플러시와 커밋 전)와 매핑된 테이블에 쿼리를 보내 조회하는 경우에 변경된 내용이 조회 결과에 반영되도록 하기 위해 매번 flush 해야 한다고 했다. 그러나 어제 공부한 내용에 따르면 JPQL을 통해 DB에 쿼리가 발생하면 JPA가 flush를 먼저 자동으로 수행해 준다고 한다. 따라서 트랜잭션 내에서 변경된 엔티티가 쿼리 결과에 반영되도록 하기 위해서 flush를 매번 할 필요는 없는 것이다.

더티 체킹

그때 더티 체킹(dirty checking)이라는 용어도 오갔는데 어제 공부하며 이해할 수 있었다. JPA의 영속성 컨텍스트는 엔티티를 처음 보관할 때의 상태를 스냅샷으로 가지고 있다. 그리고 flush 하는 시점에 엔티티 상태와 스냅샷을 비교해서 변경된 엔티티에 대해서는 수정 쿼리를 생성해서 처리해 준다고 한다.

학습자료

  • 자바 ORM 표준 JPA 프로그래밍 (김영한 저)
profile
소프트웨어 엔지니어, 일상

0개의 댓글