-
체크예외와 언체크(런타임) 예외에서의 트랜잭션스프링/스프링 기초DB 2023. 4. 1. 15:48
스프링에서 체크 예외와 언체크 예외에서의 트랜잭션이 다르게 진행된다.
체크 예외 : 비즈니스 의미가 있을 때 사용
언체크 예외 : 복구 불가능한 예외
체크 예외일 때는 트랜잭션이 커밋되고 언체크 예외에서는 트랜잭션이 롤백된다.
@Transactional(rollbackFor = MyException.class)
물론 체크 예외에서도 롤백을 하고 싶다면 위와 같이 rollbackFor을 넣어주면 롤백을 하게된다.
OrderService.class
@Slf4j @Service @RequiredArgsConstructor public class OrderService { private final OrderRepository orderRepository; // JPA는 트랜잭션 커밋 시점에 Order 데이터를 DB에 반영한다. @Transactional public void order(Order order) throws NotEnoughMoneyException { log.info("order 호출"); orderRepository.save(order); log.info("결제 프로세스 진입"); if (order.getUsername().equals("예외")) { log.info("시스템 예외 발생"); throw new RuntimeException("시스템 예외"); } else if (order.getUsername().equals("잔고부족")) { log.info("잔고 부족 비즈니스 예외 발생"); order.setPayStatus("대기"); throw new NotEnoughMoneyException("잔고가 부족합니다"); } else { // 정상 승인 log.info("정상 승인"); order.setPayStatus("완료"); } log.info("결제 프로세스 완료"); } }
NotEnoughMondyException는 별도로 만든 체크 예외이다.
런타임 예외가 발생했을 때에 롤백이 무조건 이루어진다. 체크 예외가 발생했을 때에는 커밋이 이루어지며 별도의 설정이 있지 않다면 롤백되지 않는다.
@Test void runtimeException() { // given Order order = new Order(); order.setUsername("예외"); // when Assertions.assertThatThrownBy(() -> orderService.order(order)) .isInstanceOf(RuntimeException.class); // then Optional<Order> orderOptional = orderRepository.findById(order.getId()); assertThat(orderOptional.isEmpty()).isTrue(); // 롤백되어서 데이터가 없어짐 }
테스트코드에서 런타임 예외가 발생했을 때를 실행시켜보면 롤백되어서 아예 데이터가 존재하지 않는다.
@Test void bizException() { // given Order order = new Order(); order.setUsername("잔고부족"); // when try { orderService.order(order); } catch (NotEnoughMoneyException e) { log.info("고객에게 잔고 부족을 알리고 별도의 계좌로 입금하도록 안내"); } // then Order findOrder = orderRepository.findById(order.getId()).get(); assertThat(findOrder.getPayStatus()).isEqualTo("대기"); }
반면에 잔고부족인 경우의 체크 예외가 발생했을 때에는 롤백되지 않고 데이터가 남아져있으며 고객에서 별도의 안내를 하도록 try-catch가 된 것을 확인할 수 있다.
런타임 예외는 복구 불가능한 예외로 인지되기때문에 무조건 롤백이 되는 반면에 체크 예외는 롤백이 안되고 커밋된다는 것을 알 수 있다.
'스프링 > 스프링 기초DB' 카테고리의 다른 글
스프링 트랜잭션 전파 - REQUIREDS_NEW (물리 트랜잭션 분리) (0) 2023.04.02 스프링 트랜잭션 전파(propagation) (0) 2023.04.02 트랜잭션 AOP 주의사항 - 프록시 내부 호출 (0) 2023.04.01 데이터 접근 기술 - Querydsl (0) 2023.03.28 스프링 데이터 JPA (0) 2023.03.26