결론부터 말하자면,
스프링 트랜잭션중에 하나인 Requires_new 의 트랜잭션 스레드는 독립적이지 않다.
스프링 트랜잭션의 독립이란 물리적인것이 아닌 논리적 독립을 의미할 것이다.
아래 테스트 코드를 살펴보자.
OuterClass에서 addItem() 에서 InnerService의 addCount()를 호출하고 addCount() 는 REQUIRES_NEW 의 속성을 갖는다.
새로운 독립적인 트랜잭션을 갖는다면 새로운 스레드를 생성하는것이 아닐까 착각할 수 있지만
아래와 같이 같은 쓰레드 값을 가진다.
그래서 만약, 아래처럼 InnerClass 에서 Exception 이 발생한다면 Propagation.REQUIRES_NEW 의 속성을 가졌다고 하더라도
아래처럼 outerService로 InnerClass의 Exception 이 전파된다.
단일 스레드로 스택에서 Exception 이 발생했기 때문이다.
인터넷에서 확인해 보았을때는 @Async 를 사용하는 것이 하나의 방안이라고 했다. (권장하지 않음)
아래처럼 InnerClass 에 @Async 를 붙여서 Exception 이 발생시키고 다시 테스트 해보았을때에는
아래처럼 두개의 스레드로 생성 되어 Exception 이 전파되지 않고 count 만 그대로 rollback 됨을 알 수 있다.
(스택을 공유하지 않기 때문, 사실 이것이 내가 생각했던 트랜잭션 독립의 시나리오 였다)
새로운 독립적인 트랜잭션을 생성한다는 것은 메서드가 트랜잭션 컨텍스트에서 호출될때 관련이 있음을 알 수 있다.
REQUIRES_NEW 를 사용하는 것은 하나의 스레드에 둘 이상의 트랜잭션을 가짐을 의미한다.
'spring' 카테고리의 다른 글
[토비의 스프링 3.1] 3장 - 템플릿/콜백의 응용 (0) | 2022.05.01 |
---|---|
[REDIS] Generic Redis Template 사용하기 (0) | 2022.02.09 |
Quartz Tutorials 정리(중) (2) | 2021.10.16 |
[Spring Batch] 잡 관리 컴포넌트 - 1. JobExplorer (0) | 2021.10.13 |
[Spring Boot 실행 오류]The Tomcat connector configured to listen on port 8080 failed to start. The port may already be in use or the connector may be misconfigured. (0) | 2019.08.18 |