BACK END/java spring(egov)

Spring Boot에서 @Transactional의 RollBack

자코린이 2024. 11. 11. 17:30
 
개요
  • 문제 상황
  • Transactional Annotation
  • 예외의 종류
  • 해결 방법

문제 상황

@Transactional를 사용하여 데이터를 저장하는 과정에서 예외가 발생하여 저장 과정 전체가 RollBack이 되길 원했지만, 예상과는 달리 RollBack이 발생하지 않았습니다.

Transactional Annotation

찾아보니 @Transactional 과 rollback에 관한 글은 많이 있었습니다.

대표적으로 우아한 기술 블로그 에 올라온 글이 있습니다. 감사합니다 구인본 선생님…! 🙇‍♂️

결론부터 말하면 기본적으로 예상된 에러는 RollBack을 실행하지 않습니다.

이 내용에 대해 설명하기 위해서는 예외의 종류에 대해 알아야 합니다.

예외의 종류

Error는 개발 외적인 부분에서 발생하는 것으로 대체가 불가능 하지만, Exception의 경우에는 개발자가 처리가능합니다.

예외도 2가지로 나뉘게 됩니다.

  1. 컴파일러가 체크한 예외(CheckedException) ⇒ Error, RuntimeException을 제외한 모든 예외
  2. 컴파일러가 체크하지 못한 예외(UnCheckedException) ⇒ Error, RuntimeException

여기서 2번인 UnCheckedException이 발생하는 경우에 RollBack이 일어나게 됩니다.

그 외에도 try-catch안에 속한 예외의 경우에는 RollBack이 되지 않습니다.

(제 경우가 이 경우였습니다.)

@Transactional
public void generateException() {
    ...
    try {
        throw new RuntimeException();
    }catch (RuntimeException e){
        ...
    }
}

try-catch문 안의 RuntimeException이 있는 경우 RollBack이 발생하지 않는 이유는 try-catch문에서 예외를 처리하였기 때문입니다.

해결 방법

제가 처리한 부분은 2가지 입니다.

  1. 간단한 방법은 RollBack이 필요한 부분을 try-catch문에서 분리하여 새로운 try-catch문으로 만들어주는 방법
  2. 예외를 정의해 주고 해당 예외를 rollbackFor 정의

2-1) CheckedException의 경우

아래처럼 rollbackFor로 예외를 선언해줘야 RollBack이 발생합니다.

@Transactional(rollbackFor = {MyException.class})

2-2) RuntimeException을 상속받아 새로운 예외를 생성하는 경우(위 설정은 필요하지 않습니다.)

지금까지 try-catch문에서도 예외가 발생하는 경우에는 RollBack이 되는 줄 알았습니다.

이번에 그것이 아니라는 것을 배운 계기가 되었습니다.

여기까지 긴 글 읽어주셔서 감사합니다.

제 글이 도움이 되었으면 합니다.