Java

@Transactional은 모든 예외에 rollback이 될까?

킹갓홍 2023. 11. 29. 15:21

이전에 @Transactional이 무엇인가에 대해 간단하게 알아봤었다.

그런데 "@Transcational 어노테이션은 모든 예외에 rollback이 될까?" 라는 질문에 해당 내용을 좀 더 정리 해야겠다고 생각을 했다.

"@Transcational은 모든 예외에 rollback이 될까?"

정답은 아니다.

@Transactional디폴트로 RuntimeException(UnCheckedException)과 Error에 대해서 롤백 정책을 설정한다.

그렇기에 @Transactional의 기본값을 사용하면, CheckException이 발생했을 때 롤백이 되지 않는다.

//메일 보내기
@Transactional(rollbackFor = {RuntimeException.class, Error.class})
    public String sendMail(MailDTO mailDto) {
        dao.saveMail(mailDto);
    // 생략 ... 
}

@Transactional을 기본값으로 쓰게 될 경우 위 코드와 같은 형태라고 볼 수 있다.

CheckedException이 롤백이 되도록 하기 위해서는 rollbackFor옵션을 사용해서 특정 예외에 대해서 처리해주던가, rollbackFor = {Exception.class} 라고 써서 모든 예외에 전부 롤백 처리를 걸어주면 된다.

 

** rollbackFor를 명시한 경우, 롤백 정책을RuleBasedTransactionAttribute 클래스rollbackRules 리스트에 저장하고 예외 발생 시 해당 클래스의 rollbackOn 메서드에서 rollbackRules를 확인하여 어떤 롤백 정책에 따를 것인가를 선출(winner)한다.
비어있을 경우 기본정책(RuntimeException/Erorr)를 따른다.

"그러면 http 외부호출(외부 API)은 롤백될까?"

외부API를 호출하고 RuntimeExceoption을 발생시킨다면 롤백이 될까?
정답은 아니다.

외부 API를 호출했을 때는 RuntimeException(UnCheckedException)이라 하더라도 롤백이 되지 않는다.

"스프링에서는 어떻게 @Transactionl만 붙이는데 commit rollback이 지원되는걸까?"

스프링부트에서 @Transactional 어노테이션을 붙여주면, SpringConfiguration파일@EnableTransactionManagement 를 자동으로 붙여주고 SpringConfiguration에서 트랜잭션 매니저를 지정한다.

이후, @Transactional이 붙은 빈이 상속하고 있는 인터페이스를 상속해서 동적으로 프록시를 만들고,
추상 메서드를 오버라이딩 한 뒤 전 후로 트랜잭션을 처리하게 된다.

@Transactional 적용 전/후   출처:https://hwannny.tistory.com/98

트랜잭션 처리가 아니더라도 부가기능을 독립적으로 추출하고 핵심기능을 타겟에 부여하는 기술이 AOP이다.

 

 


참고자료

https://pjh3749.tistory.com/269

https://blogshine.tistory.com/291

https://junuuu.tistory.com/818

https://hwannny.tistory.com/98