@Transactional은 모든 예외에 rollback이 될까?
이전에 @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
이 붙은 빈이 상속하고 있는 인터페이스를 상속해서 동적으로 프록시를 만들고,
추상 메서드를 오버라이딩 한 뒤 전 후로 트랜잭션을 처리하게 된다.
트랜잭션 처리가 아니더라도 부가기능을 독립적으로 추출하고 핵심기능을 타겟에 부여하는 기술이 AOP이다.
참고자료
https://pjh3749.tistory.com/269
https://blogshine.tistory.com/291