예외가 발생했는데… 내부에서 예외를 처리못하고 트랜잭션범위 밖으로까지 예외가 날아가면 어떻게 될까?
위 그림과 같이 예외가 Controller단까지 던져진 상태이다.
코드로 테스트해보자…
package hello.springtx.exception;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;
@SpringBootTest
public class RollbackTest {
@Slf4j
static class RollbackServcie {
//런타임 예외 발생: 롤백
@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 checkedExceptionRollbackFor() throws MyException {
log.info("call checkedExceptionRollbackFor");
throw new MyException();
}
}
static class MyException extends Exception{}
}
각각의 상황을 재현할 메서드들을 만들어주자.
그리고 테스트 환경을 구축한다.
@Autowired
RollbackServcie rollbackServcie;
@TestConfiguration
static class RollbackTestConfig {
@Bean
RollbackServcie rollbackServcie() {
return new RollbackServcie();
}
본격적으로 테스트 해보자.
@Test
void runtimeException() {
Assertions.assertThatThrownBy(() -> rollbackServcie.runtimeException())
.isInstanceOf(RuntimeException.class);
}
트랜잭션 인터셉터를 통해 알아보면… 커밋된건지 롤백된건지 확실치가 않다. 그냥 Completing~
이라는 메시지만 출력되고 있다.
더 자세히 알기 위해 로그 옵션을 다음처럼 줘보자..
logging.level.org.springframework.transaction.interceptor=TRACE # 기존에 있던 설정
#추가 설정
logging.level.org.springframework.jdbc.datasource.DataSourceTransactionManager=DEBUG
#JPA log
logging.level.org.springframework.orm.jpa.JpaTransactionManager=DEBUG
logging.level.org.hibernate.resource.transaction=DEBUG