예외와 트랜잭션

나무·2023년 11월 25일

스프링 DB2

목록 보기
2/4
post-thumbnail

1. 체크예외, 언체크예외

체크 예외

  1. Exception 의 하위 예외 중 런타임 예외(자식 포함)를 제외한 모든 예외들
  1. 반드시 에러를 처리 혹은 throws를 추가 해줘야한다.

언 체크 예외

  1. 런타임 예외와 그 자식들
  1. 컴파일러가 예외 처리를 강제하지 않기 때문에 따로 처리할 필요가 없다.

2. 예외 발생시 커밋과 롤백

스프링에서는 트랜잭션 처리과정에서 예외가 발생하면 예외에 따라 달리 처리하게된다.

언체크 예외 -> 자동 롤백
체크 예외 -> 자동 커밋

(※ 어디까지나 기본값이 그렇다는거고 실제로는 optional 이다.)

왜 체크 예외는 커밋을 해?

혹자들은 체크 예외 발생시 커밋을 하는 것에 대해

"예외가 발생했는데 왜 커밋을 하지?"

라고 의아해 할 수도 있는데 여기에는 다음과 같은 이유가 있다.

스프링은 예외의 종류별로 다음과 같이 가정을 한다.

언체크 예외 : 복구 불가능 (시스템 예외)
체크 예외 : 복구 가능 (비즈니스 예외)

시스템 예외 란,

말 그대로 시스템에 예외가 발생한 경우다.

예를 들어,

네트워크 지연,
SQL 에러,
메모리 부족,
서버 다운

과 같이 시스템에 문제가 발생한 경우에는 거의 대부분의 경우 사실상 복구가 불가능하다. 무슨말이냐면 예외를 try-catch 로 잡아봤자 개발자가 딱히 할 수 있는게 없다는 뜻이다.

그렇기 때문에 수행되었던 트랜잭션을 다시 문제 발생 이전으로 되돌려 놓는것이다.

반면 비즈니스 예외는,

이런 시스템적인 에러가 아니라 논리적인 경우에 발생한 예외를 뜻한다.

예를 들어

고객의 잔액이 부족하여 주문에 실패한 경우,

입력했던 주문데이터들을 전부 롤백 시켜버리기 보다는 DB에 일단 저장(커밋)을 하되 주문테이블에 status 라는 컬럼을 하나 두어서 "대기" 라는 값으로 저장을 해놓는다.

그 다음 try-catch 로 예외를 잡은다음 고객에게 "잔액이 부족합니다" 라는 메시지를 전송하여 고객이 금액을 충전한다음 다시 주문을 시도하면 주문 상태가 "성공" 으로 바뀌게 되고 정상적인 주문 데이터가 저장이 된다. 즉, 예외를 복구한 셈이다.

예외 발생시 무조건 롤백하기(rollbackFor 옵션)

물론, 스프링에서는 비즈니스/시스템 예외 구분없이 모두 롤백 시키는 방법도 존재한다.

	@Transactional(rollbackFor = Exception.class)
    public void order(Order order) throws NotEnoughMoneyException {
    	// 주문 처리 로직
    }

@TransactionalrollbackFor 옵션을 사용하면 다음과 같이 예외마다 롤백을 수행할지 말지를 정할 수 있다.

(※ 하지만 예외들을 구분하지 않게끔 설계를 하고싶다면 @Transactional 마다 옵션을 설정할 필요없이 애초에 모든 예외를 언체크 예외로 감싸버리면 된다.)

본 포스트는
김영한의 스프링 DB 2편 - 데이터 접근 활용 기술 강의 를 보고 정리했습니다.

profile
🍀 개발을 통해 지속 가능한 미래를 만드는데 기여하고 싶습니다 🍀

0개의 댓글