Java 예외 처리 모델과 관련성
- Checked Exception:
- 컴파일러에서 반드시 처리해야 하는 예외.
- 호출부에서 명시적으로 try-catch로 처리하거나 throws로 위임해야 합니다.
- 예: IOException, SQLException.
- Unchecked Exception (RuntimeException):
- 컴파일러에서 강제하지 않는 예외.
- 프로그램의 논리적 오류 또는 예측 불가능한 상황에서 발생.
- 예: NullPointerException, IllegalArgumentException.
Spring 트랜잭션 관리 설계 철학
Spring의 트랜잭션 롤백 정책은 다음과 같은 가정을 기반으로 합니다:
- Checked Exception은 복구 가능성:
- Checked Exception은 애플리케이션이 복구할 가능성이 있는 예외로 간주됩니다.
- 따라서 Checked Exception이 발생했을 때는 롤백하지 않고, 애플리케이션이 상황에 따라 처리하도록 설계된 것입니다.
- 예: 파일을 찾을 수 없는 경우, 새로운 파일 경로를 제공하거나 기본값으로 동작하도록 설계.
- Unchecked Exception은 복구 불가능성:
- Unchecked Exception은 애플리케이션의 논리적 오류나 시스템의 중단 상황을 나타냅니다.
- 복구가 어렵다고 간주되므로 자동으로 트랜잭션을 롤백하도록 기본 동작이 설정됩니다.
- 예: 데이터베이스 연결 중단, null 참조 접근.
Spring의 기본 롤백 정책
- 기본적으로 Spring의 @Transactional은 다음과 같은 정책을 따릅니다:
- RuntimeException 및 그 하위 클래스 발생 시 → 트랜잭션 롤백.
- Checked Exception 발생 시 → 트랜잭션 커밋(롤백하지 않음).
- Error 발생 시 → 트랜잭션 롤백.
왜 이런 동작이 필요할까?
- 프레임워크의 유연성과 예외의 의도 반영:
- Checked Exception은 예외 상황에서 복구하려는 의도를 반영합니다. 따라서 Spring은 이를 "비정상 종료"로 간주하지 않고, 애플리케이션에서 처리하도록 설계합니다.
- 반면, Unchecked Exception은 보통 복구 불가능한 심각한 오류를 나타내므로 트랜잭션 롤백을 트리거하는 것이 합리적입니다.
- 호환성과 개발자 편의성:
- Java의 기존 예외 처리 모델과 호환되며, Checked Exception을 처리해야 하는 경우 개발자가 명시적으로 트랜잭션 롤백을 지정할 수 있습니다.
Checked Exception에 대해 롤백을 원한다면?
Spring에서는 기본 동작을 변경하여 Checked Exception에서도 트랜잭션을 롤백할 수 있습니다. 이를 위해 @Transactional의 rollbackFor 속성을 사용합니다:
@Transactional(rollbackFor = Exception.class)
public void myMethod() throws Exception {
// Checked Exception도 롤백되도록 설정
throw new IOException("Checked Exception 발생");
}
- rollbackFor: 롤백할 예외를 지정.
- noRollbackFor: 롤백하지 않을 예외를 지정.
정리
Spring에서 RuntimeException은 기본적으로 트랜잭션 롤백의 대상이 되는 반면, Checked Exception은 그렇지 않은 이유는 다음과 같습니다:
- 복구 가능성에 대한 차이:
- Checked Exception은 복구 가능성이 있다고 간주.
- RuntimeException은 복구 불가능한 오류로 간주.
- Spring의 기본 설계 철학:
- 애플리케이션이 의도적으로 Checked Exception을 처리하도록 유도.
필요하다면 Spring의 @Transactional 설정을 통해 기본 정책을 재정의할 수 있습니다.
'Spring > Spring JPA' 카테고리의 다른 글
[JPA] @Transactional 속성(attribute) (1) | 2024.12.26 |
---|---|
[JPA] @DynamicUpdate 간단히 (0) | 2024.12.26 |
[JPA] 영속성 캐시(Persistence Context) (0) | 2024.12.05 |
[JPA] generate-ddl과 ddl-auto 차이 (1) | 2024.12.04 |
[JPA] hibernate.ddl-auto (0) | 2024.12.04 |