트랜잭션과 예외 처리

조승빈·2025년 1월 17일

Spring DB

목록 보기
7/8

트랜잭션 전체 흐름

  1. 트랜잭션 시작
  • 개발자가 직접 트랜잭션을 시작하거나, 스프링에서는 @Transactional어노테이션을 통해 자동으로 트랜잭션이 시작된다.
  • 트랜잭션이 시작되면 DB는 자동 커밋 모드를 비활성화한다.
  1. SQL 실행
  • 이 명령의 결과는 즉시 디스크에 저장되지 않고 메모리의 트랜잭션 버퍼에 기록된다.
  1. 커밋 or 롤백
  • 트랜잭션 중 문제가 발생하지 않으면 커밋을 실행하여 모든 변경 사항을 디스크에 반영한다.
  • 오류가 발생하면 롤백하여 모든 변경 사항을 취소한다.

트랜잭션 로그 버퍼
데이터베이스 내부에 있는 임시 저장 공간이다. 커밋 전에 모든 작업이 여기에 기록된다.


비즈니스 예외 처리

스프링은 트랜잭션 처리 시 예외의 종류에 따라 다음과 같은 전략을 사용한다.
1. 체크 예외 (Checked Exception)

  • 컴파일 타임에 확인되는 예외.
  • 일반적으로 비즈니스 로직에서 의미가 있는 예외에 사용된다.
  • 기본적으로 체크 예외가 발생해도 트랜잭션을 롤백하지 않고 커밋한다.
  • 필요 시 @Transactional(rollbackFor = SomeCheckedException.class)를 사용해 롤백할 수 있다.
  1. 언체크 예외 (Unchecked Exception)
    • RuntimeException을 상속한 예외로, 컴파일 타임에 강제되지 않는다.
    • 복구가 불가능한 예외 처리에 사용된다.
    • 언체크 예외가 발생하면 스프링은 기본적으로 롤백한다.

비즈니스 예외 처리의 예제

다음은 결제 잔고 부족을 비즈니스 예외로 처리하면서 트랜잭션을 커밋하거나 롤백하는 예제이다.

1. 비즈니스 예외 클래스

public class InsufficientBalanceException extends Exception {
    public InsufficientBalanceException(String message) {
        super(message);
    }
}

2. 주문 서비스에서 트랜잭션 처리

@Service
public class OrderService {
    
    @Transactional(rollbackFor = InsufficientBalanceException.class)
    public void placeOrder(OrderRequest orderRequest) throws InsufficientBalanceException {
        // 주문 생성
        Order order = createOrder(orderRequest);

        // 결제 처리
        if (!processPayment(orderRequest)) {
            order.setPaymentStatus("PENDING");
            throw new InsufficientBalanceException("잔고가 부족하여 결제가 대기 상태로 처리되었습니다.");
        }

        // 결제가 성공하면 주문 완료
        order.setPaymentStatus("PAID");
    }

    private boolean processPayment(OrderRequest orderRequest) {
        // 잔고 체크 로직 (가상의 처리)
        return orderRequest.getBalance() >= orderRequest.getAmount();
    }
}

3. 설명

  • placeOrder 메서드는 @Transactional 애너테이션을 사용하여 트랜잭션을 관리한다.
  • InsufficientBalanceException체크 예외이지만, rollbackFor 옵션을 사용하여 롤백 대상에 포함시켰다.
  • processPayment 메서드가 false를 반환하면 결제 상태를 대기로 설정하고 예외를 발생시킨다.
  • 이 예외는 롤백을 트리거하며 데이터베이스에 반영되지 않는다.
profile
평범

0개의 댓글