본문 바로가기
프로젝트

트랜잭션(Transaction) 이해

by jucheol 2025. 9. 24.

1. 트랜잭션이란?

트랜잭션은 데이터베이스 작업의 최소 단위입니다.

  • 여러 작업(쿼리)을 하나로 묶어 모두 성공(commit) 하거나 모두 실패(rollback) 시키는 역할을 합니다.
  • 예: 주문 서비스
    • 재고 차감 성공 + 주문 생성 성공 → commit
    • 재고 차감 성공 + 주문 생성 실패 → rollback (재고 차감도 되돌아감)

즉, 업무의 일관성을 보장하기 위한 핵심 개념입니다.


2. 트랜잭션 범위 지정 (@Transactional)

Spring에서는 @Transactional 애노테이션으로 트랜잭션의 범위를 지정할 수 있습니다.

 
@Service
public class OrderService {
    @Transactional
    public void order(Long itemId, Long userId) {
        // 1. 재고 차감
        itemRepository.decreaseStock(itemId);

        // 2. 주문 생성
        orderRepository.save(new Order(userId, itemId));
    }
}

특징

  • order() 메서드 전체가 하나의 트랜잭션으로 묶임
  • 둘 중 하나라도 실패 → 전체 롤백
  • 모든 과정이 성공해야만 commit

이 방식으로 “재고 차감과 주문 생성은 항상 함께 성공/실패해야 한다”는 업무 규칙을 보장할 수 있습니다.


3. 낙관적 락 vs 비관적 락

트랜잭션과 밀접하게 연관된 개념이 락(lock) 입니다.

  • 비관적 락
    • 트랜잭션이 시작되자마자 DB row에 락을 걸어 다른 트랜잭션이 접근하지 못하게 함
    • 장점: 충돌을 확실히 방지
    • 단점: 동시성 높은 환경(예: 티켓팅)에서는 대기 시간이 길어져 성능 저하
  • 낙관적 락
    • 락을 걸지 않고, 트랜잭션 종료 시점에 버전(Version) 값을 비교해 충돌 감지
    • 장점: 락 오버헤드 없음, 트래픽이 적을 때 효율적
    • 단점: 충돌 시 롤백 → 재시도 필요

정리: 트래픽이 적은 환경에서는 낙관적 락이, 티켓팅 같은 고트래픽 환경에서는 비관적 락이나 큐/분산락 같은 다른 설계가 필요합니다.


4. 트랜잭션 전파 옵션 (Propagation)

업무 시나리오에 따라 트랜잭션을 같이 묶을지, 따로 처리할지를 지정할 수 있습니다.

  • REQUIRED (기본값)
    • 기존 트랜잭션이 있으면 합류, 없으면 새로 생성
    • 주문 서비스 기본 시나리오
  • REQUIRES_NEW
    • 무조건 새로운 트랜잭션 시작
    • 예: 주문 실패해도 포인트 차감은 반드시 반영해야 하는 경우
  • MANDATORY
    • 무조건 기존 트랜잭션 안에서 실행, 없으면 예외 발생
  • SUPPORTS
    • 트랜잭션 있으면 합류, 없어도 그냥 실행 (읽기 전용 작업에 적합)
  • NOT_SUPPORTED / NEVER
    • 트랜잭션 없이 실행 (로그 기록, 알림 발송 등)

업무 규칙에 따라 트랜잭션 경계를 조절하는 게 핵심입니다.


5. 업무 시나리오 예시

  • 주문 처리
    • @Transactional(REQUIRED) → 재고 차감 + 주문 생성은 항상 함께 처리
  • 포인트 적립
    • @Transactional(REQUIRES_NEW) → 주문 실패해도 포인트 적립은 보장
  • 알림 발송
    • @Transactional(NOT_SUPPORTED) → 알림은 실패해도 본 주문 로직에는 영향 없음

6. 정리

  • 트랜잭션은 업무 단위의 원자성을 보장하는 장치
  • @Transactional로 범위를 지정해 함께 성공/실패할 작업을 명확히 표현
  • 전파 옵션을 통해 업무 규칙에 맞는 트랜잭션 경계를 설정
  • 락 전략(낙관적/비관적)은 트래픽 상황업무 특성에 맞게 선택