개인 프로젝트를 진행하고 나서, 협업 개발자 분의 코드 리뷰가 있었다.
정말 수많은 피드백이 있었지만, 그 중 트랜잭션에 대한 내용이 있었다.
@Transactional이 필요한 곳에 없는 경우가 있다는 것이었다.
덧붙여서 트랜잭션에 대한 이해를 하고 @Transactional을 적재적소에 사용해야 한다는 피드백이 있었다.
그래서 블로그 글에 해당 내용을 작성하며 트랜잭션과 @Transactional이 어떤 상황에 필요한지 공부를 하고, 프로젝트에 적절히 적용시킬 계획이다.
ACID를 정리하면 다음 예와 같다.
"결제는 다른 사람과 독립적으로 이루어지며 그 작업 중 다른 연산 작업이 끼어들 수 없다.
작업 도중 오류가 생긴 경우 연산을 취소하고 작업 실행 전으로 되돌린다.
성공할 경우 결과를 영구적으로 반영한다.
@Transactional이 붙은 메서드가 실행될 경우, 우선 spring에서는 해당 메서드에 대한 프록시를 생성한다. (프록시 패턴은 디자인 패턴 중 하나로, 어떠한 코드를 감싸면서 추가적인 연산을 수행하도록 강제하는 방법이다.)
트랜잭션의 경우, 작업의 시작과 종료시에 커밋 과정, 혹은 작업 도중 실패시 롤백 과정이 필요하므로 프록시를 생성해 해당 메서드의 연산과정의 처음과 끝에 추가하는 것이다.
트랜잭션(데이터 연산)의 과정 - 송금
위의 연산 과정 중에 예를 들어 a가 b의 계좌를 잘못 입력해 b의 계좌 정보를 찾는 데 실패했다고 가정하자.
그럼 a의 계좌에서 돈이 빠졌는데, b의 계좌의 잔액은 그대로인 것이다. 중간에 10000원이 없어진 것이다.
이러한 상황을 방지해야 한다.
위의 연산을 하나의 트랜잭션으로 지정하고 관리한다면, 만약 3번 작업에 실패했다면 1, 2번 작업도 취소가 되고 그 처리 과정 전으로 되돌아 가는 것이다
만약 모든 연산이 성공했다면, 그 결과를 DB에 영구적으로 반영하고 저장한다.