Transaction(트랜잭션) & @Transactional

minjjai·2022년 11월 14일
0

개요

개인 프로젝트를 진행하고 나서, 협업 개발자 분의 코드 리뷰가 있었다.
정말 수많은 피드백이 있었지만, 그 중 트랜잭션에 대한 내용이 있었다.
@Transactional이 필요한 곳에 없는 경우가 있다는 것이었다.
덧붙여서 트랜잭션에 대한 이해를 하고 @Transactional을 적재적소에 사용해야 한다는 피드백이 있었다.
그래서 블로그 글에 해당 내용을 작성하며 트랜잭션과 @Transactional이 어떤 상황에 필요한지 공부를 하고, 프로젝트에 적절히 적용시킬 계획이다.

Transaction

정의

  • 데이터베이스 시스템에서 상호작용의 단위(더 이상 쪼개질 수 없는 최소의 연산)
  • 데이터베이스의 상태를 변화시키기 위해 수행하는 작업의 단위
    데이터베이스의 상태를 변화시킨다는 것은 SQL을 이용해 데이터베이스에 접근하는 것을 의미한다.

특징 - ACID

원자성 - Atomicity

  • 트랜잭션이 데이터베이스에 모두 반영되던지, 아니면 모두 반영되지 않아야 한다.

일관성 - Consistency

  • 트랜잭션의 작업 처리 결과는 항상 일관되어야 한다.

독립성(격리성) - Isolation

  • 둘 이상의 트랜잭션이 동시에 실행되고 있을 경우, 어떤 트랙잭션이라도 다른 트랜잭션의 연산에 끼어들 수 없다.

지속성(영속성) - Durability

  • 트랜잭션이 성공적으로 완료되었을 경우, 그 결과는 DB에 영구적으로 반영되어야 한다.

ACID 정리 예

ACID를 정리하면 다음 예와 같다.

"결제는 다른 사람과 독립적으로 이루어지며 그 작업 중 다른 연산 작업이 끼어들 수 없다.
작업 도중 오류가 생긴 경우 연산을 취소하고 작업 실행 전으로 되돌린다.
성공할 경우 결과를 영구적으로 반영한다.

Commit & Rollback

Commit

  • 하나의 트랜잭션이 성공적으로 끝이 났고, DB가 일관된 상태일 때, 하나의 트랜잭션이 끝났다는 것을 알려주기 위한 연산이다.
  • commit 사용시 실행된 트랜잭션은 로그에 저장되며 작업 도중 추후에 rollback연산 수행시 해당 commit지점으로 되돌아 간다.

Rollback

  • 트랜잭션의 처리 도중 비정상적으로 종료된 경우, 트랜잭션을 다시 시작하거나 부분적으로 연산된 결과를 다시 취소한다.(되돌린다)

@Transactional 어노테이션

  • 클래스나 메서드에 붙여주는 경우, 해당 범위의 메서드가 트랜잭션이 되도록 보장해준다.
  • 선언적 트랜잭션

@Transaction의 작동 원리 & 흐름

@Transactional이 붙은 메서드가 실행될 경우, 우선 spring에서는 해당 메서드에 대한 프록시를 생성한다. (프록시 패턴은 디자인 패턴 중 하나로, 어떠한 코드를 감싸면서 추가적인 연산을 수행하도록 강제하는 방법이다.)
트랜잭션의 경우, 작업의 시작과 종료시에 커밋 과정, 혹은 작업 도중 실패시 롤백 과정이 필요하므로 프록시를 생성해 해당 메서드의 연산과정의 처음과 끝에 추가하는 것이다.

Ex

트랜잭션(데이터 연산)의 과정 - 송금

a가 b의 계좌로 10000원을 송금한다.

  1. a의 계좌잔액 정보를 가져온다.
  2. a의 계좌에서 10000원을 뺀다.
  3. b의 계좌잔액 정보를 가져온다.
  4. b의 계좌에 10000원을 더한다.

위의 연산 과정 중에 예를 들어 a가 b의 계좌를 잘못 입력해 b의 계좌 정보를 찾는 데 실패했다고 가정하자.
그럼 a의 계좌에서 돈이 빠졌는데, b의 계좌의 잔액은 그대로인 것이다. 중간에 10000원이 없어진 것이다.
이러한 상황을 방지해야 한다.
위의 연산을 하나의 트랜잭션으로 지정하고 관리한다면, 만약 3번 작업에 실패했다면 1, 2번 작업도 취소가 되고 그 처리 과정 전으로 되돌아 가는 것이다
만약 모든 연산이 성공했다면, 그 결과를 DB에 영구적으로 반영하고 저장한다.

profile
BackEnd Developer

0개의 댓글