728x90
/**
* memberService @Transactional:ON
* memberRepository @Transactional:ON
* logRepository @Transactional:ON Exception
*/
@Test
public void outerTxOn_fail() {
//given
String username = "로그예외_outerTxOn_fail";
//when
assertThatThrownBy(() -> memberService.joinV1(username))
.isInstanceOf(RuntimeException.class);
;
//then : 모든 데이터가 롤백된다.
assertTrue(memberRepository.find(username).isEmpty());
assertTrue(logRepository.find(username).isEmpty());
}
- MemberService = @Transactional:ON
- MemberRepository = @Transactional:ON
- LogRepository = @Transactional:O
- 로그 예외를 전달했으므로 런타임 예외 발생

- 클라이언트 A가 MemberService를 호출하면서 트랜잭션 AOP가 호출된다.
- 여기서 신규 트랜잭션이 생성되고, 물리 트랜잭션도 시작한다.
- MemberRepository를 호출하면서 트랜잭션 AOP가 호출된다.
- 이미 트랜잭션이 있으므로 기존 트랜잭션에 참여한다.
- MemberRepository의 로직 호출이 끝나고 정상 응답하면 트랜잭션 AOP가 호출된다.
- 트랜잭션 AOP는 정상 응답이므로 트랜잭션 매니저에 커밋을 요청한다. 이 경우 신규 트랜잭션이 아니므로 실제 커밋을 호출하지 않는다.
- LogRepository 를 호출하면서 트랜잭션 AOP가 호출된다.
- 이미 트랜잭션이 있으므로 기존 트랜잭션에 참여한다.
- LogRepository 로직에서 런타임 예외가 발생한다. 예외를 던지면 트랜잭션 AOP가 해당 예외를 받게 된다.
- 트랜잭션 AOP는 런타임 예외가 발생했으므로 트랜잭션 매니저에 롤백을 요청한다. 이 경우 신규 트랜잭션이 아니므로 물리 롤백을 호출하지는 않는다. 대신에 rollbackOnly를 설정한다.
- LogRepository 가 예외를 던졌기 때문에 트랜잭션 AOP도 해당 예외를 그대로 밖으로 던진다.
- MemberService 에서도 런타임 예외를 받게 되는데, 여기 로직에서는 해당 런타임 예외를 처리하지 않고 밖으로 던진다.
- 트랜잭션 AOP는 런타임 예외가 발생했으므로 트랜잭션 매니저에 롤백을 요청한다. 이 경우 신규 트랜잭션이므로 물리 롤백을 호출한다.
- 참고로 이 경우 어차피 롤백이 되었기 때문에, rollbackOnly 설정은 참고하지 않는다.
- MemberService 가 예외를 던졌기 때문에 트랜잭션 AOP도 해당 예외를 그대로 밖으로 던진다.
- 클라이언트 A는 LogRepository부터 넘어온 런타임 예외를 받게 된다.
728x90
'스프링 DB 2편(데이터 접근 활용 기술)' 카테고리의 다른 글
| Ch11. 스프링 트랜잭션 전파(활용) - 복구 REQUIRES_NEW (0) | 2022.07.08 |
|---|---|
| Ch11. 스프링 트랜잭션 전파(활용) - 복구 REQUIRED (0) | 2022.07.08 |
| Ch11. 스프링 트랜잭션 전파(활용) - 전파 커밋 (0) | 2022.07.08 |
| Ch11. 스프링 트랜잭션 전파(활용) - 단일 트랜잭션 (0) | 2022.07.08 |
| Ch11. 스프링 트랜잭션 전파(활용) - 서비스 계층에 트랜잭션이 없을 때 (커밋, 롤백) (0) | 2022.07.08 |