[Spring]@Transactional에서 예외발생 시 커밋과 롤백
스프링의 트랜잭션 AOP에서는 예외의 종류에 따라 트랜잭션을 커밋하거나 롤백한다.
- 롤백하는 경우 : RuntimeException, Error와 그 하위 예외
- 커밋하는 경우 : Exception과 그 하위 예외 / 정상적으로 종료되는 경우(예외 미발생)
예외 구분 | 트랜잭션 | ||||
Object | Throwable | Error | LinkageError | 롤백 | |
ThreadDeath | 롤백 | ||||
.. 기타 에러 | 롤백 | ||||
Exception | RuntimeException | unChecked | 롤백 | ||
SQLException | checked | 커밋 | |||
… 기타 예외 | checked | 커밋 |
아래 예제코드를 참조하자
@SpringBootTest public class RollbackTest { @Autowired RollbackService service; @Test @DisplayName("RuntimeException은 트랜잭션을 롤백한다.") void runtimeExceptionTest() { assertThatThrownBy(() -> service.runtimeException()) .isInstanceOf(RuntimeException.class); } @Test @DisplayName("CheckedException은 트랜잭션을 커밋한다.") void checkedExceptionTest() { assertThatThrownBy(() -> service.checkedException()) .isInstanceOf(MyException.class); } @Test @DisplayName("지정된 CheckedException은 트랜잭션을 롤백한다.") void rollbackForExceptionTest() { assertThatThrownBy(() -> service.rollbackFor()) .isInstanceOf(MyException.class); } @TestConfiguration static class RollbackTestConfig { @Bean RollbackService rollbackService() { return new RollbackService(); } } @Slf4j static class RollbackService { // 런타임 예외 발생 : 롤백 @Transactional public void runtimeException() { log.info("call runtimeException"); throw new RuntimeException(); } // 체크 예외 발생 : 커밋 @Transactional public void checkedException() throws MyException { log.info("call CheckedException"); throw new MyException(); } // 체크 예외 rollbackFor 지정 : 롤백 @Transactional(rollbackFor = MyException.class) public void rollbackFor() throws MyException { log.info("call rollbackFor"); throw new MyException(); } } static class MyException extends Exception { } }
최신 댓글