@Transactional을 쓰는 이유는?

유수민·2022년 7월 11일
1

FoodMall 프로젝트

목록 보기
10/14

📌 Transactional이란?

페이징 처리하는 서비스를 보면 @Transactional 이 붙어있다. 이게 무엇일까?

간단하게 말하면, 트랜잭션은 데이터베이스의 상태를 변환시키는 하나의 논리적 기능을 수행하기 위한 작업의 단위 또는 한꺼번에 모두 수행되어야 할 일련의 연산들을 의미한다. 하지만 문장만으로는 이해가 안된다. 이해를 위해 예시를 들자면, A사람이 B사람에게 5만원을 송금하는 과정에서 이 과정
을 위해

A 사람의 통장 : 5만원 출금

B 사람의 통장 : 5만원 입금

이 발생하게 된다. 근데 중간에 오류가 발생한다면?
A사람은 분명히 5만원이 출금되었는데, B사람의 통장에는 입금된게 없는 상황이 발생될 수 있다. 이처럼, 예상하지 못한 상황에서 오류가 발생하여 하여 데이터의 부정합이 발생하는 경우, 다시 원상복귀 해야 하는 상황에 대비 하기 위해 Transactional 을 사용한다. 비정상 처리되어 데이터의 부정합이 발생한다면 원래 상태로 원상 복귀하고, 정상적으로 프로그램이 진행되었다면 데이터에 최종적으로 적용하게 되어 데이터의 부정합을 방지할게 되는 것이다.

앞서서 Transaction을 간단히 설명할때 Transaction을 데이터베이스의 상태를 변환시키는 하나의 논리적 기능을 수행하기 위한 작업의 단위 또는 한꺼번에 모두 수행되어야 할 일련의 연산들을 의미한다고 말했다. 예시에서 A사람의 통장에서 5만원이 출금되고, B사람의 통장에서는 5만원이 입금되는 과정을 하나의 논리적 기능이라고 할 수 있다. 즉, 프로그램상에서 본다면, Transaction은 2개 이상의 쿼리를 하나의 커넥션으로 묶어 DB에 전송하고, 이 과정에서 에러가 발생할 경우 자동으로 모든 과정을 되돌려 놓는 역활을 해준다.

📖@Transactional의 필요성

페이징 처리하는 서비스에는 쿼리문이 1개뿐인데? @Transactional을 써줘야 해?

@Transactional은 주로 여러 쿼리문이 있을때 사용한다. 하지만 보다시피 쿼리문이 1개만 사용하고 있기 때문에 데이터 변경이 없이 데이터를 읽어들이는 단순 조회의 기능만을 하고 있다는 생각이든다. 따라서, 굳이 이 어노테이션이 필요한가에 대한 의문이 든다.

단순히 조회의 기능이라면, 읽기전용인 @Transactional(readOnly = true)으로 바꿔줘도 될 것이다.

사실 @Transactional을 없애도 에러없이 작동하는데 아무 문제가 없다. 그런데 왜 써줘야만 할까? 알아본 바에 의하면, 정상적인 상황인 경우 readOnly는 트랜잭션 범위는 유지하되 조회 기능만 남겨두어 조회 속도가 개선되게 하기위해 사용한다고 한다.
참고) https://pakker.tistory.com/90

📖왜 속도가 개선 되지??

트랜잭션에 readOnly=true 옵션을 주면 하이버네이트의 Session Flush Mode를 FlushMode.MANUAL로 설정하게 되어 강제로 플러시를 호출하지 않는 한 플러시가 일어나지 않게 된다.

flush가 일어나지 않는다는 말은, 아래 작업이 수행되지 않는다는 말이다

1) 엔티티의 등록, 수정, 삭제
2) Dirty checking을 위한 스냅샷 비교

따라서 트랜잭션을 커밋하여도 영속성 콘텍스트가 flush 되지 않아서 엔티티의 등록, 수정, 삭제가 동작하지 않으며 추가적으로 영속성 콘텍스트에서 변경 감지를 위한 스냅샷을 보관하지 않아 무거운 로직을 수행하지 않아도 되어서 성능이 보다 향상이 된다고 한다.

Flush 란?

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

Dirty checking 이란?

Dirty란 상태의 변화가 생긴 정도로 Dirty checking은 상태 변경 검사 를 말한다.

Dirty checking은 Transaction 안에서 엔티티의 변경이 일어나면, 변경 내용을 자동으로 데이터베이스에 반영하는 JPA 특징이다.

참고) https://interconnection.tistory.com/121

profile
배우는 것이 즐겁다!

0개의 댓글