일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Ehcache
- lazyloading
- 리팩터링
- 동시성
- Metaspace
- JDK14
- nonclustered index
- Spring Data Redis
- 트랜잭션
- 부하테스트
- backend
- 웹캐시
- 제네릭
- B+TREE
- CaffeineCache
- ci/cd
- method area
- JAVA8
- 재고 시스템
- 지연로딩
- JPA
- Jenkins
- GithubActions
- 주문
- springboot
- 상태패턴
- 카카오 화재
- 공변
- java
- Redis
- Today
- Total
NDM
[Java] Java Exception과 Spring Transaction 본문
Java의 Checked Exception과 UnCheckedException을 검색하다 보면 이런 표를 쉽게 찾을 수 있습니다.
이 표의 일부 내용은 맞으면서도 틀렸습니다. 어떤게 틀렸을까요??
CheckedException / UnCheckedException
Java의 Exception은 Throwable 하위의 객체들입니다.
그중에서도 Error는 메모리부족이나 시스템 오류같이 개발자가 접근해서는 안되는 오류들이고,
Exception 객체가 개발자가 신경써야 할 영역이라고 보시면 됩니다.
때문에 그냥 제일 위에있는 객체로 예외처리를 하기 위해 throw Throwable을 한다던가 하시면 안됩니다.
CheckedException
- 반드시 예외처리를 해야합니다. 안그러면 컴파일 오류에서 잡힙니다
- 잡아서 호출한 곳으로 던지거나, 처리를 반드시 해야합니다
- Exception을 상속받기만 하면 체크 예외로 분류됩니다
- 컴파일 시점에 모두 잡아주니 편하다고 생각할 수 있지만, 모든 예외의 경우를 처리해줘야 하며, 의존관계의 문제점도 있습니다
UncheckedException
- Exception하위의 RuntimeException을 상속받는 객체입니다
- 컴파일러가 예외 체크 하지 않습니다
- 예외처리를 생략할 수 있습니다. 하나하나 잡아서 처리하거나 하지 않아도 됩니다. 단, 처리하지 않으면 자동으로 호출한 곳으로 던지는 것은 같습니다. "throws XXXException" 을 생략할 수 있다는 말입니다. 의존관계의 문제도 없습니다
- 단, 생략이 가능하다보니 개발자가 예외 처리를 가끔 누락할 수 있다는 단점이 있습니다.
지금, 맨 위의 표에서 한가지를 설명하지 않았습니다. 바로 롤백 여부입니다.
CheckedException / UnCheckedException 은 기본적으로 트랜잭션 롤백과 관련이 없습니다.
RuntimeException이 터지면 자동적으로 트랜잭션은 롤백되긴 하지만, 이는 Exception 자체와 관련이 있는것이 아닌, Spring Transaction과 관련이 있습니다. 때문에 맞으면서도 틀렸다고 한 것입니다.
Spring Transaction과 Rollback
Spring Transaction 의 Propagation Level은 기본적으로 Required로 동작합니다. 이를 염두해 두세요
TransactionAspectSupport.java 에 가보시면, 이런 코드를 발견할 수 있습니다
rollbackOn()이라는 메소드가 보이네요
The default behavior is as with EJB: rollback on unchecked exception (RuntimeException), assuming an unexpected outcome outside any business rules. Additionally, we also attempt to rollback on
Error which is clearly an unexpected outcome as well
rollbackOn 메소드의 공식 문서에서 발췌한 글입니다. 대충 번역해보면,
비즈니스 로직 중 예상 할수 없었던 예외(RuntimeException) 또는 Error에 대해서는 Rollback을 한다는 내용입니다.
또한, setGlobalRollbackOnParticipationFailure()의 주석에서도 이러한 글을 발견할 수 있습니다
If a participating transaction (e.g. with * PROPAGATION_REQUIRED or PROPAGATION_SUPPORTS encountering an existing transaction) fails, the transaction will be globally marked as rollback-only.
참여중인 트랜잭션(Required나 Support 전파레벨)이 실패한다면, 트랜잭션은 rollback-only 마크를 한다
The only possible outcome of such a transaction is a rollback: The transaction originator <i>cannot</i> make the transaction commit anymore.
가능한 결과는 롤백뿐이며, 최초의 트랜잭션도 더이상 커밋할 수 없다
결국 요약하면, 트랜잭션 실행 중 내부 트랜잭션에서 런타임 예외가 터지면 최초의 트랜잭션도 전역 롤백이 되어버린다는 겁니다. 기본적으로 스프링 트랜잭션 전파레벨은 Required이기 때문에 맨 위의 표가 만들어졌던 것이죠
참조
https://techblog.woowahan.com/2606/
https://devlog-wjdrbs96.tistory.com/351
https://deveric.tistory.com/86
'Java' 카테고리의 다른 글
[Java] lambda에서 final변수만 사용 가능한 이유 - 멀티스레드의 비밀 (0) | 2022.09.15 |
---|---|
[Java] 자바 동작 원리와 JVM 3편 : Garbage Collector (0) | 2022.08.08 |
[Java] Java8 MetaSpace (0) | 2022.08.05 |
[Java] Java Generic은 어떻게 동작할까? (0) | 2022.05.09 |
[Java] GC와 Java Reference Type 1편 : Java Reference Type (0) | 2022.05.01 |