[TIL] Spring의 트랜잭션(Transaction) 이해

김재진·2026년 2월 4일

내일배움캠프

목록 보기
47/70

1. 트랜잭션(Transaction)이란?

데이터베이스의 상태를 변화시키기 위해 수행하는 작업의 단위를 의미. "전부 성공하거나, 아니면 아예 실패하거나(All or Nothing)"라는 원칙을 통해 데이터의 정합성을 보장.

ACID 원칙

  • Atomicity(원자성): 한 트랜잭션 내의 모든 작업은 하나의 단위로 처리된다. (중간 실패 시 모두 취소)
  • Consistency(일관성): 완료 후 데이터는 비즈니스 규칙을 항상 만족해야 한다.
  • Isolation(격리성): 동시 실행되는 트랜잭션들이 서로 방해하지 못하게 격리한다.
  • Durability(지속성): 성공한 결과는 시스템 장애가 발생해도 영구적으로 기록된다.

2. Spring에서의 @Transactional

스프링은 AOP(Aspect Oriented Programming)를 이용하여 선언적 트랜잭션을 지원한다. 개발자는 비즈니스 로직에만 집중하고, 트랜잭션의 시작과 종료(Commit/Rollback)는 스프링 프록시가 대신 처리한다.

동작 원리
1. 대상 메서드가 호출되면 스프링이 프록시(Proxy) 객체를 통해 트랜잭션을 가로챈다.
2. 메서드 실행 전 Transaction Manager를 통해 트랜잭션을 시작한다.
3. 성공 시 Commit, 예외 발생 시 Rollback 처리를 수행한다.

3. 결제 시스템에서의 실전 적용

과제에서 사용하는 PortOne 결제 프로세스를 예시로 트랜잭션의 중요성을 정리했다.

주요 로직 흐름

  • 주문 생성: 재고 확인 + 주문 레코드 생성 + 포인트 차감 (하나의 트랜잭션)
  • 결제 확정: 결제 상태 변경 + 재고 차감 확정 + 멤버십 등급별 포인트 적립 (하나의 트랜잭션)

코드 예시 (Java/Spring)

@Transactional(rollbackFor = Exception.class)
public void confirmPayment(String orderId, String paymentId) {
    // 1. 주문 상태 변경
    Order order = orderRepository.findById(orderId);
    order.setStatus(OrderStatus.PAID);

    // 2. 멤버십 등급별 적립 로직 (Normal 1%, VIP 5%, VVIP 10%)
    long rewardPoint = calculationPointByMembership(order);
    pointService.addPoint(order.getUserId(), rewardPoint);

    // 3. 재고 확정 처리
    stockService.confirmStock(order.getProductId());
    
    // 이 메서드 안에서 하나라도 에러가 나면 1, 2, 3번 모두가 실행 전으로 롤백됨
}

4. 주의사항

  1. Private 메서드 사용 불가: @Transactional은 프록시 기반이므로 외부에서 호출 가능한 public 메서드여야 한다.
  2. Self-invocation(자기 호출): 동일 클래스 내의 메서드끼리 호출하면 프록시를 타지 않아 트랜잭션이 적용되지 않는다.
  3. Checked Exception: 기본적으로 RuntimeException만 롤백하므로, IOException 등 일반 예외에도 롤백이 필요하면 rollbackFor 옵션을 써야 한다.

5. 오늘을 마치며

결제 시스템처럼 돈과 재고가 얽힌 로직에서는 트랜잭션 설정 하나가 서비스의 신뢰도를 결정한다. 단순히 어노테이션을 붙이는 것에 그치지 않고, 전파(Propagation) 속성이나 격리 수준에 대해서도 깊게 공부해야 할 필요성을 느꼈다.

profile
개발공부 처음해보는 사람

0개의 댓글