스프링 DB 2편(데이터 접근 활용 기술)

Ch11. 스프링 트랜잭션 전파(활용) - 전파 롤백

webmaster 2022. 7. 8. 18:25
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