개인 프로젝트에서는 쓴 적이 없던, 회사에서 처음 본 속성이다.
그것은 바로 @Transactional의 noRollbackFor 속성.
간단히 말하면 이름 그대로 롤백이 일어나지 않도록 하는 속성이다.
대부분의 비즈니스 로직이 실행되는 Service 단에서 각 메서드마다 @Transactional 어노테이션을 붙여 메서드 내부의 작업들이 하나의 트랜잭션으로 묶여 처리되도록 한다.
물론, Service 단이 아닌 Controller 단에서도 불가피하게 호출하는 Service 단의 메서드가 많다면.. 해당 어노테이션을 사용해 하나의 트랜잭션으로 묶을 수 있다.
이 때, 호출된 해당 트랜잭션이 수행되던 중 어떠한 이유로 에러가 발생한다면 묶여있는 모든 트랜잭션이 rollback 처리가 된다.
하지만! 특정한 Exception에서는 rollback이 일어나지 않도록 하고 싶을 경우가 있을 수 있다.
이 때, @Transactional의 'noRollbackFor' 속성을 이용한다.
예를 들면, 하나의 트랜잭션으로 묶인 특정 메서드를 호출할 때 일관성보다는 현재까지 수행된만큼이라도 롤백되지 않고 DB에 저장이 되거나 서비스 로직이 수행되는 것이 조금 더 중요하다거나..하는 경우가 있다면 해당 속성을 사용하면 된다.
아래는 사용방법이다.
@Transactional(noRollbackFor = { RuntimeException.class, NoSuchMethodException.class })
public void insertItem() {
...
}
noRollbackFor 속성에 정의한 Exception이 해당 트랜잭션 내부에서 발생할 경우, 수행된 부분까지 commit이 발생하며 rollback이 진행되지 않는다.
위 예시와 같이 한 번에 여러 개의 Exception을 명시할 수 있다.
그리고 속성에 사용될 수 있는 Exception class는 Throwable의 자식클래스여야 한다.
사실 앞서 말했듯 이걸 처음 보고 굳이 저 속성을 왜 쓰지?..라는 생각을 했다.
해당 속성을 쓰는 순간 @Transactional을 사용해 하나의 트랜잭션으로 묶는 의미가 줄어든다고 생각했기 때문이다.
/* 여기는 제가 그냥 듣고 생각했던 과정을 적어두었으니..그냥 지나가셔도 됩니다..😅 */
우선은..다른 DB에서 수많은 데이터를 갖고 와서 Controller를 거쳐 Service 단으로 와서 수많은 로직을 거치는데, 여기서 데이터가 의도치 않게 유실되어..? 트랜잭션 안의 어떤 특정 로직을 수행하지 못해도 우선 다른 로직들은 수행되어야 해서..
그러니까 (내가 이해한 바로는) 해당 트랜잭션에서는 일관성 있는 처리보다는 수행된 부분까지 commit되는 것이 더 중요해서 해당 속성을 사용한 것이라고..그렇다고 한다.