Java Checked, Unchecked Exception Rollback에 대해 정확히 알기
업데이트:
보통 Java Checked Exception
, Unchecked Exception
에 대해 공부하다 보면 항상 등장하는 부분이 있습니다.
Checked Exception / Unchecked Exception
1. Checked Exception
1) 반드시 예외를 처리해야 함
2) Rollback 하지 않음
2. Unchecked Exception
1) 명시적인 처리를 강제하지 않음
2) Rollback 함
이번 포스팅은 정말 이 명제가 정확한지 확인하는 포스팅입니다.
Exception
먼저 Java의 Exception
에 대해서 간단히 알아도보록 하겠습니다.
위에 그림은 Java의 오류 관련 클래스들의 계층 구조인데, 여기서 Error
는 시스템에 비정상적인 상황(OutofMemoryError
, StackOverflowError
등)이 발생했을 경우이기 때문에 개발자 들이 예측하기도, 처리하기도 어렵습니다.
따라서, 저는 Exception
만 알아보도록 하겠습니다.
Exception
은 프로그래밍 적으로 처리 가능한 오류를 뜻하는데, 위의 그림을 보면 하위에 Checked Exception
과 RuntimeException
을 상속받은 Unchecked Exception
이 있습니다.
Checked Exception
Checked Exception
은 다음과 같은 특징이 있습니다.
- 반드시 예외처리를 해야한다.
- 컴파일 단계에서 발생
위와 같은 속성에 따라 Checked Exception
은 intelliJ같은 IDE에서 예외처리를 강요합니다.
즉, 컴파일 단계에서 발생한다고 알수 있죠. 따라서 Checked Exception
은 반드시 try ~ catch
문이나 throws
로 Exception
을 처리해줘야 합니다.
그럼 대표적인 Checked Exception
으로는 IOException
, SQLException
이 있는데 간단한 예로 다음과 같은 상황을 상상해보겠습니다.
Jdbc에서 DB와 connection을 맺고자 할때 DB가 구동중이지 않는 상황.
이때 어떤 Exception
이 발생하게 될까요?
저는 MariaDB와 Connection을 맺으려고 하고 있으며 사용된 driverClass 역시 org.mariadb.jdbc.Driver
입니다.
위와 같이 SQLNonTransientConnectionException
이 발생한 것을 확인할 수 있습니다.
발생한 ConnectionHelper
클래스의 connectSocket()
메소드로 가서 Exception
이 발생한 곳으로 가보면 다음과 같이 IOException
을 try ~ catch
로 명시적으로 처리해주는것을 알 수 있습니다.
Unchecked Exception
Unchecked Exception
은 다음과 같은 특징이 있습니다.
- 명시적인 처리를 강제하지 않는다.
- 실행(Runtime) 단계에서 발생한다.
대표적인 Unchecked Exception
으로는 NullPointException
, IllegalArgumentException
등이 있습니다.
IllegalArgumentException
를 발생시킬 때 try ~ catch
나 throws
로 처리하지 않더라도 IDE에서 컴파일에러가 발생하지 않는것을 볼 수 있고, 이는 실행(Runtime)에서 Exception
이 발생할 것임을 유추할 수 있습니다.
❗그러나 이것이
Exception
처리를 하지 않는다는 뜻은 아님을 아셔야 합니다. “명시적인 처리를 강제하지 않는다.” 전 이말을 “그럼Exception
에 대한 후 처리를 안해도 되나?”라고 바보같이 오해한적이 있습니다. 강제하지 않을 뿐이지 후 처리는 어떻게든 반드시 하셔야 합니다. 공통적인ExceptionHandler
등을 통하여 유저 메시지를 출력한다든지, 로그를 쌓는다든지, 슬랙 등으로 알림을 보낸다든지Exception
상황에 대처하기 위해 필요한 후 처리는 반드시 필요합니다.
클린코드 Unchecked Exception
클린코드에서는 Unchecked Exception
사용을 권장하고 있는데 여러 이유가 있겠지만 제일 주된 이유는 Checked Exception
는 OCP(Open/Closed Principal)를 위배하기 때문입니다. 위에서 update()
메소드에서 SQLException
같은 Checked Exception
을 throws
로 호출한 메소드로 던지고 있다면, 호출한 모든 메소드에 영향이 가게 되고 따라서 OCP(Open/Closed Principal)를 위배하게 됩니다.
이런 이유로 클린코드에서는 Unchecked Exception
사용을 권장하고 있습니다.
그 밖에도 클린코드에서 말하는 예외처리도 있는데, 이는 다른 포스트에서 다뤄보도록 하겠습니다.
Rollback
그럼 이번엔 이번 포스트에 핵심 내용인 Exception
과 관련된 Rollback을 보도록 하겠습니다.
Checked Exception
, Unchecked Exception
을 공부하시는 분들이라면 한 번쯤 다음 문구를 보신적이 있으실텐데요.
예외 발생 시 트랜잭션 처리
1. Checked Exception - Rollback 하지 않음
2. Unchecked Exception - Rollback 함
저도 예전에는 구글링한 자료에서 좀 이상은 했지만 그래도 설마싶어서 그냥 외웠는데요. 백기선님의 영상을 보고 다시 공부하게 되었습니다. (반성합니다…)
결론부터 말하자면 “Java Exception의 종류와 DB 트랜잭션 Rollback은 아무 상관이 없다.” 입니다.
그럼 제대로된 내용은 무엇일까?
💡먼저 용어부터 정확히 하고 넘어가겠습니다. 보통
Exception
에 종류와 Rollback에 관한 내용을 말할 때, 나오는 트랜잭션은 DB 트랜잭션을 뜻합니다.
아마 여러 블로그들에 있는 Exception
와 Rollback에 관련 내용들은 Spring에서의 Exception
종류에 따른 Rollback 정책으로 부터 나온 오인된 내용이 아닐까 싶습니다.
위의 링크에서 16.5.3 Rolling back a declarative transaction을 보시면 아래와 같은 내용이 있습니다.
In its default configuration, the Spring Framework’s transaction infrastructure code only marks a transaction for rollback
in the case of runtime, unchecked exceptions; that is, when the thrown exception is an instance or subclass of RuntimeException.
( Errors will also - by default - result in a rollback).
Checked exceptions that are thrown from a transactional method do not result in rollback in the default configuration.
RuntimeException
은 기본적으로 Rollback 처리하고, Checked Exception
은 Rollback을 하지 않는다고 적혀있습니다.
또한, Spring은 다양한 옵션을 통해 Rollback에 대한 처리를 개발자가 Optional하게 처리할 수 있도록 지원하고 있습니다.
다음은 @Transactional
어노테이션에서 지정할 수 있는 속성표이고, 빨간 박스는 Rollback과 관련된 옵션들 입니다.
마무리
이 포스트를 보신 분들이라면 다음 내용을 확실히 기억하시기 바랍니다.
“Java Exception 종류와 DB 트랜잭션 Rollback과는 아무런 관련이 없다.”
“Spring의 Exception 발생 시 트랜잭션 기본 동작은 RuntimeException은 Rollback 처리하고, Checked Exception은 Rollback하지 않는다.”
“Spring의 Exception 발생에 대한 동작 옵션들을 지원하기 때문에 개발자가 지정할 수 있다.”
저 역시 잘못된 내용을 학습했고, 의심이 있었음에도 공식문서 등을 확인해볼 노력을 안했기 때문에 이런 내용을 답습하게 된것 같습니다.
좀 더 확실히 공부하도록 노력을 더 기울여야겠습니다.
저와 비슷한 경험을 하셨을 분들께서 이번 포스트가 도움이 되셨으면 좋겠습니다.
오늘도 긴 제 글을 읽어주셔서 감사합니다. 😀
댓글남기기