@Transactional Annotation

NNIIE·2021년 11월 23일
0

spring

목록 보기
3/12

트랜잭션이란 ?

데이터베이스 트랜잭션은 데이터베이스 관리 시스템 또는 유사한 시스템에서 상호작용의 단위이다.

여기서 단위라는 말을 사용했는데, 쉽게 말하면 더 이상 쪼개질 수 없는 최소의 연산이라는 의미가 된다.

예를 들어보자. 만약 내가 쇼핑 앱을 켜서 상품을 구매하려고 한다.

그런데 내가 결제를 하는 짧은 시간 사이에 아래와 같은 일이 벌어지면 어떨까?

  • 해당 판매자가 상품의 가격을 바꿔버려서, 잘못된 금액이 결제됨
  • 같은 상품을 다른 사람도 구매해서, 상품 재고는 1개인데 2명에게 결제됨
  • 결제가 완료되기 직전에 네트워크가 끊겨서, 돈은 나갔지만 구매완료는 되지 않음

아무래도 황당할 수밖에는 없다.

위의 예외적 상황을 막기 위해서, 다음과 같은 조치가 필요할 것이다.

  • 내가 결제중일 때에는 해당 상품의 정보를 바꿀 수 없게 함
  • 내가 결제중일 때에는 해당 상품을 다른 사람이 결제하지 못하게 함
  • 내 구매가 오류로 완료되지 않았다면, 결제된 금액을 환불 처리함

위의 조치사항을 좀 더 간략하게 정리하면, 아래와 같이 정리할 수 있다.

"결제는 다른 사람과 독립적으로 이루어지며, 과정 중에 다른 연산이 끼어들 수 없다.

오류가 생긴 경우 연산을 취소하고 원래대로 되돌린다. 성공할 경우 결과를 반영한다."

여기서 결제는 트랜잭션의 예시로 든 것이다. 트랜잭션 역시, 위의 원칙을 바탕으로 한다.

그래서 어떤 연산에 트랜잭션이 보장된다면, DB에서 의도치 않은 값이 저장되거나 조회되는 것을 막을 수 있다.

1. 원자성(Atomicity)
한 트랜잭션 내에서 실행한 작업들은 하나로 간주한다. 즉, 모두 성공 또는 모두 실패

2. 일관성(Consistency)
트랜잭션은 일관성 있는 데이타베이스 상태를 유지한다. (data integrity 만족 등.)

3. 격리성(Isolation)
동시에 실행되는 트랜잭션들이 서로 영향을 미치지 않도록 격리해야한다.

4. 지속성(Durability)
트랜잭션을 성공적으로 마치면 결과가 항상 저장되어야 한다.

@Transactional 어노테이션

@Transactional은 클래스나 메서드에 붙여줄 경우, 해당 범위 내 메서드가 트랜잭션이 되도록 보장해준다.
선언적 트랜잭션이라고도 하는데, 직접 객체를 만들 필요 없이 선언만으로도 관리를 용이하게 해주기 때문.
특히나 SpringBoot에서는 선언적 트랜잭션에 필요한 여러 설정이 이미 되어있는 탓에, 더 쉽게 사용할 수 있다.

동작원리

@Transactional 어노테이션을 기준으로 설명하자면.
트랜잭션은 Spring AOP를 통해 구현되어있다.
더 정확하게 말하면, 어노테이션 기반 AOP를 통해 구현되어있다. (import문을 보면 알 수 있다)

import org.springframework.transaction.annotation.Transactional;
  • 클래스, 메소드에 @Transactional이 선언되면 해당 클래스에 트랜잭션이 적용된 프록시 객체 생성
  • 프록시 객체는 @Transactional이 포함된 메서드가 호출될 경우, 트랜잭션을 시작하고 Commit or Rollback을 수행
  • CheckedException or 예외가 없을 때는 Commit
  • UncheckedException이 발생하면 Rollback

사용법

DB와 관련된, 트랜잭션이 필요한 서비스 클래스 혹은 메서드에 @Transactional 어노테이션을 달아주면된다.
클래스, 메서드 모두에 @Transactional 어노테이션을 붙이면 메서드 레벨의 @Transactional 선언이 우선 적용된다.
@Transactional이 붙은 메서드는 메서드가 포함하고 있는 작업 중에 하나라도 실패할 경우 전체 작업을 취소한다.

0개의 댓글