Search

트랜섹션과 플러시

Tags
JPA
Date
2023/09/28

개요

본 포스팅은 김영한님의 자바 ORM 표준 JPA 프로그래밍 - 기본편을 기반으로 작성되었습니다. 다만 플러시를 이해하기 위해서 트랜섹션의 개념을 보다 더 확실히 해야 하기 때문에 몇몇 내용들을 추가하였습니다.

1. 트랜섹션은 언제 사용될까?

스프링 서버 개발을 하다보면 다음과 같은 의문점이 생길 때가 있습니다.
저장을 할 때는 save(), 삭제를 할 때는 delete() 메서드를 호출 하는데 왜 수정할 때는 수정할 내용만 setter 메서드를 사용해서 업데이트하고 그 내용을 저장하지 않을까?
그 내용의 발단은 이렇습니다.
예를 들어, 글의 내용을 수정하는 코드가 있다고 가정 해봅시다.
@Transactional public Post update(Long postId, PostCreateDto postCreateDto){ Post post = postRepository.findById(postId).orElseThrow( () -> new PostNotFoundException()); post.update(postCreateDto); return post; }
Java
복사
만약 스프링 개발에 익숙하지 않은 사람이라면 수정된 내용을 저장하지 않았는데 반영이 되는지 의문을 표하는 분들이 계실 수도 있습니다.
이는 메서드 위에 붙어있는 어노테이션, @Transactional 때문에 가능한 일입니다.

2. 트랜섹션이란?

데이터베이스 트랜잭션은 데이터베이스 관리 시스템 또는 유사한 시스템에서 상호작용의 단위입니다.
데이터베이스의 상태를 변경시키기 위해 수행하는 작업 단위 또는 한꺼번에 모두 수행되어야 할 일련의 연산을 의미합니다.
예를 들어, 티켓팅을 생각해봅시다.
분명히 비어 있는 좌석을 선택했는데, 결제를 하려고 하면 “이미 선택된 좌석입니다”라는 문구를 자주 보게 된다.
자리를 조회할 때는 빈 좌석이었지만, 누군가가 나와 같은 좌석을 선택하고 나보다 빠르게 먼저 결제까지 성공했다면, 나의 결제 시도는 실패하고 내가 선택한 자리는 내 것이 아니게 된다.
내가 선택했던 자리와 결제 정보들이 커밋되지 않고 롤백되는 것이다.
자리를 선택하고 결제까지 완료하는 작업 단위가 하나의 트랜잭션이라고 볼 수 있다.
트랜잭션이 걸려있지 않다면, 같은 자리를 여러 명이 결제하게 되는 문제가 발생할 수 있다.

@Transactional 어노테이션

@Transactional을 클래스나 메서드에 붙이면, 해당 범위가 트랜잭션이 되도록 보장해준다.
적용된 범위에서는 프록시 객체가 생성되어 자동으로 커밋(commit) 또는 롤백(rollback)을 진행한다.
예외 발생 시, rollback을 통해 DB에 결과가 반영되지 않는다.

3. 플러시란?

위의 예제를 이어나가봅시다.
만약 좌석을 선택하고 결제까지 완료 했다면 트랜섹션 커밋 (Transaction Commit) 이 일어나게 됩니다. 트랜섹션 커밋이 일어날 때 플러시가 동작하는데, 이 때 쓰기 지연 저장소에 쌓아 놨던 INSERT, UPDATE, DELETE SQL들이 데이터베이스에 날라갑니다.
이 때 주의할 점은 플러시가 동작한다고 해서 영속성 컨텍스트에 있는 엔티티들이 비워지는 것이 아닙니다.
플러시영속성 컨텍스트변경 사항들과 관계형 데이터베이스 사이의 상태를 맞추는 동기화 작업입니다.
 플러시는 어떻게 동작하나요?
플러시의 동작 과정은 다음과 같습니다.
1.
변경을 감지합니다. (Dirty Checking)
2.
수정된 엔티티를 쓰기 지연 SQL 저장소에 등록합니다.
3.
쓰기 지연 SQL 저장소의 Query를 DB에 전송합니다. (등록, 수정, 삭제 Query)
실제로는 플러시가 발생하고 그 이후에 커밋이 발생합니다.
플러시트랜섹션이 시작되고 해당 트랜섹션커밋되는 시점에만 동기화 해주면 되기 때문에 플러시 매커니즘의 동작이 가능한 것입니다.
영속성 컨텍스트플러시하는 방법은 다음과 같습니다.
1.
em.flush()를 활용한 직접 호출
2.
트랜섹션 커밋을 활용한 자동 호출
3.
JPQL 쿼리 실행을 통한 자동 호출
더 자세한 내용은 후에 실습을 통해 확인해보겠습니다 :)