• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

강의의 롤백 커밋 기준에 대해 추가로 궁금한 점이 있습니다.

22.12.30 20:35 작성 22.12.30 20:44 수정 조회수 356

0

1. 강의 내용과 관련된 질문인가요? (예)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (아니오)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)

[질문 내용]


이전 강의 예외와 트랜잭션 커밋, 롤백 - 기본에서

 

예외 발생시 트랜잭션 내부에서 예외를 처리하지 못하고, 트랜잭션 범위 밖으로 예외를 던지면,

스프링은 기본적으로
언체크 예외 = 롤백
체크 예외 = 커밋 한다고 배웠습니다.

그리고 본 강의 활용에서 체크 예외와 언체크 예외를 통해 커밋과 롤백이 되는 것을 확인할 수 있었는데요.


여기서 제가 궁금한 것은 일단 언체크 예외도 명시적으로 던지지 않아도 catch 해서 처리할 수 있다고 알고 있습니다.

그러면 스프링이 언체크 예외를 롤백시키는 기준이 트랜잭션 내에서 언체크 예외를 처리하지 못하고 범위 밖으로 던졌을 때에만 롤백하는 것인가요?

즉, 해당 트랜잭션 내에서 언체크 예외를 잡아서 처리하면 트랜잭션 범위 밖으로 언체크 예외가 던져졌기 않았기 때문에 해당 트랜잭션이 롤백되지 않고 커밋 되나요?


예를 들어 아래의 코드와 같이 트랜잭션은 OrderServiceorder() 메서드에서 실행되고, couponService를 통해 주문한 고객에게 쿠폰을 1개 우선 발행한 뒤에, 해당 트랜잭션 내에서 orderRepository.save 를 통해 DB에 주문이 저장됩니다.

(주문을 먼저 완료하고 쿠폰을 발행 해야겠지만 제 질문 상황의 명확성을 위해 예시를 이렇게 했습니다.)

  1. 하지만 orderRepository.save()메서드 실행 도중 DB에 문제가 생겨 Order가 DB에 정상적으로 저장이 되지 않아 Exception이 발생하였고 (언체크 예외) 해당 예외를 잡아서 처리했습니다. 그러면 해당 트랜잭션 밖으로 던져지는 예외는 존재하지 않으며 정상흐름대로 동작합니다. 이 경우 해당 트랜잭션은 롤백되는 것인가요 아니면 커밋되는 것인가요?

 

  1. 1번 질문에서 정상 흐름으로 바뀌었기 때문에 커밋이 된다고 하면,
    만약 RuntimeException을 잡아 체크 예외로 변경해서 해당 트랜잭션 범위 밖으로 던질 경우도 동일하게 커밋이 되는건가요?

@Transactional
public void order(Order order) {

  couponService.giveCoupon(order.getUserId));

  try { orderRepository.save(order);
  } catch (RuntimeException e) {
    // Exception을 잡아서 처리하는 로직
  }
}

 

답변 1

답변을 작성해보세요.

0

안녕하세요. shh3138님^^

해당 코드를 직접 구현해서 실행해보시면 바로 답을 얻으실 수 있을거에요^^!
(이렇게 답을 구하면 진짜 내 지식이 되지요)

그리고 구한 답을 공유해주시면 다른 분들께도 도움을 드릴 수 있을거에요.

감사합니다.

shh3138님의 프로필

shh3138

질문자

2023.01.03

해당 코드를 작성해서 실행해본 결과,
스프링은 트랜잭션 내에서의 예외 발생시 오직 언체크 예외가 트랜잭션 밖으로 던져졌을 경우에만 롤백하는 것으로 테스트 되었습니다.

추가로 런타임 예외가 발생했을 때 의도적으로 롤백 시키지 않는 방법은,
1) 해당 예외를 체크 예외로 변환해서 던진다. (Exception Handler로 잡아서 처리 가능)

2) noRollbackFor 옵션을 사용한다.

3) try - catch 문을 사용해 해당 런타임 예외를 잡아서 처리해준다.

크게 이렇게 3가지가 존재하는 것 같습니다.

확실히 직접 코드를 작성하고 이리저리 수정해가면서 확인해보니 원리도 더 잘 이해되고 실제 코드를 적용할 때 어떻게 이러한 옵션을 사용할 수 있는지 알게 되는 것 같습니다. 감사합니다.

shh3138님 직접 실행해보시고 결과도 남겨주셔서 감사합니다^^