본문 바로가기
Backend/Spring

[String] Transaction - rollback 속성

by 제이동 개발자 2025. 8. 31.
728x90

[String] Transaction - rollback 속성

1. 기본 롤백 규칙

 

  • 롤백됨(default): RuntimeException과 Error (및 그 하위 타입)
  • 롤백되지 않음: 체크 예외(Exception의 하위지만 RuntimeException이 아닌 것)

예외 패키지 구조

java.lang.Throwable
├─ java.lang.Error                       // 시스템 레벨(복구 불가) - 언체크
│  ├─ OutOfMemoryError
│  ├─ StackOverflowError
│  └─ LinkageError …
└─ java.lang.Exception                   // 애플리케이션 레벨
   ├─ (Checked Exceptions)               // 체크 예외: throws/try-catch 필요
   │  ├─ java.io.IOException
   │  │  ├─ FileNotFoundException
   │  │  ├─ EOFException
   │  │  ├─ InterruptedIOException
   │  │  │  └─ SocketTimeoutException
   │  │  └─ java.net.MalformedURLException
   │  ├─ java.sql.SQLException
   │  ├─ java.text.ParseException
   │  ├─ ClassNotFoundException
   │  ├─ TimeoutException (java.util.concurrent)
   │  └─ ReflectiveOperationException …
   └─ java.lang.RuntimeException         // 언체크(=런타임) 예외
      ├─ NullPointerException
      ├─ IllegalArgumentException
      ├─ IllegalStateException
      ├─ IndexOutOfBoundsException
      ├─ ArithmeticException
      ├─ ClassCastException
      ├─ ConcurrentModificationException
      ├─ NoSuchElementException
      ├─ UnsupportedOperationException
      └─ UncheckedIOException            // (Java 8+) IOException 래핑용 언체크

 

 

 

2. 롤백 속성

2-1. rollbackFor

 

  • 역할: 지정한 예외(타입 일치 또는 하위 타입) 발생 시 롤백
  • 사용 예시: 체크 예외(IOException, SQLException, 커스텀 체크 예외 등)에도 롤백을 적용하고 싶을 때
  // 체크 예외도 롤백시키고 싶을 때 명시
  @Transactional(rollbackFor = {IOException.class, SQLException.class})
  public void pay() throws IOException {
    // ... 비즈니스 로직
    if (/* 외부 I/O 오류 */) {
      throw new IOException("외부 결제 게이트웨이와 통신 실패");
    }
  }

 

 

2-2. rollbackForClassName

 

  • 역할: rollbackFor의 문자열 버전(FQCN).
  • 사용 예시: 컴파일 타임에 의존성을 갖지 않거나(모듈 선택적 의존), 예외 타입이 런타임에만 존재할 수 있을 때.

 

@Transactional(rollbackForClassName = {
  "java.io.IOException",
  "java.sql.SQLException"
})
public void sync() {
  // ...
}

 

 

2-3. noRollbackFor

 

  • 역할: 지정한 예외(타입 일치 또는 하위 타입)에서는 롤백하지 않음(커밋).
  • 사용 예시: 비즈니스 검증 실패처럼 “예상 가능한 오류”를 커밋으로 처리하고 싶을 때(예: 포인트 차감은 안 했지만, 일부 로그/이벤트 적재는 유지).

 

/**
 * 비즈니스 검증 실패는 커밋(롤백 금지)하고 싶을 때
 */
@Transactional(noRollbackFor = {BusinessException.class})
public void placeOrder(OrderCommand cmd) {
  // ... 선행 상태 저장(로그/감사 등)
  if (!stockService.hasEnough(cmd.getItemId())) {
    // 런타임 예외지만 noRollbackFor에 의해 커밋됨
    throw new BusinessException("재고 부족");
  }
  // ... 결제/차감
}

 

 

2-4. noRollbackForClassName

 

  • 역할: noRollbackFor의 문자열 버전(FQCN).
  • 용례: rollbackForClassName과 동일.
  • 주의: rollbackForClassName과 동일. 오타·리팩토링 취약.

 

 

 

 

 

728x90