Spring Framework에서 트랜잭션의 동작방식과 @Transactional
의 기능에 대해 살펴봅니다.
데브코스에서 @Transactional
어노테이션에 대한 강의를 듣게 되었다. 지금까지 프로젝트를 진행하면서 @Transactional
어노테이션을 사용해보긴 했지만, 트렌젝션으로 메소드를 처리하기 위해서는 사용해야하는 어노테이션이다! 정도만 알고 사용했었다. 강의를 듣다 보니 내가 지금까지 @Transactional
을 사용하면서 잘못 사용한 부분도 존재하고 생각했던 개념과 좀 다른 부분이 있는것 같아서 이참에 Spring에서 트랜잭션에 대해 자세히 알아보자! 라는 생각에 포스트를 작성하게 되었다.
Spring은
@Transactional
이나 XML을 통해 선언된 트랜잭션에 대해 Declarative Transaction(선언적 트랜잭션)이라는 표현을 사용한다.
Spring Document를 찾아보니 선언적 트랜잭션에 대해 아래와 같은 설명을 남겨두었다.
The Spring Framework’s declarative transaction management is made possible with Spring aspect-oriented programming (AOP). However, as the transactional aspects code comes with the Spring Framework distribution and may be used in a boilerplate fashion, AOP concepts do not generally have to be understood to make effective use of this code.
Spring Framework의 선언적 트랜잭션 관리는 Spring AOP(Aspect 지향 프로그래밍)를 통해 가능합니다. 그러나 트랜잭션 측면 코드는 Spring Framework 배포판과 함께 제공되고 상용구 방식으로 사용될 수 있으므로 일반적으로 이 코드를 효과적으로 사용하기 위해 AOP 개념을 이해할 필요는 없습니다.
스프링에서 선언적 트랜잭션은 비즈니스 로직에 집중할 수 있도록 AOP 관점을 적용했다. 비즈니스 로직을 작성한 후 트랜잭션 선언을 하면 트랜잭션이 구현되도록 만들어 놓았다는 것인데, 그렇다면 메서드를 호출했을때 어떤 방식으로 동작이 될까?
스프링에서 제공하는 트랜잭션 호출의 개념도를 살펴보면 AOP 프록시를 활용해서 활성화되기 시작한다는 것을 볼 수 있다.
프록시 내부에 Target Method의 실행 전후로 지정한 Custom Advisior가 실행되고, Transaction Advisior가 트랜잭션에 대한 Rollback or Commit을 결정하고 Proxy 객체를 통해 반환되는 형식으로 동작이 진행됨을 확인할 수 있다. 그렇다면 트랜잭션이 어떤 경우에 Commit될지 Rollback될지 어떻게 결정할 수 있을까??
@Transactional
살펴보기트랜잭션을 지정하기위해 @Transactional
을 사용하면 기본적으로 아래와 같이 세팅이된다.
ISOLATION_DEFAULT
이다.none
이다.RunetimeException
과 Error
가 발생하면 Rollback을 수행한다. checked Exception에 대해서는 Rollback을 수행하지 않는다.PROPAGATION_REQUIRED
를 따른다.기본적으로 트랜잭션은 RuntimeException
과 Error
발생시 Rollback을, 이외의 경우는 Commit을 실행한다. 이를 바꾸고싶다면 @Transactional
의
rollbackFor
의 값으로 Rollback을 발생시키고자 하는 Exception이나 Error Class를 Optional Array
로 전달하거나rollbackForClassName
의 값으로 Rollback을 발생시키고자 하는 Exception의 이름 패턴을 Optional Array
로 전달하거나noRollbackFor
의 값으로 Exception이 발생해도 Rollback하지 않을 Exception이나 Error Class를 Optional Array
로 전달하거나noRollbackForClassName
의 값으로 Exception이 발생해도 Rollback하지 않을 Exception의 이름 패턴을 Optional Array
로 전달더욱 자세하게 트랜잭션을 설정하고 싶다면 @Transactional
Settings을 참고하자!
Spring은 트랜잭션을 AOP 형식의 프록시로 만들고 관리한다는 점이 공부를 하면서 알게 된 가장 중요한 부분인 것 같다.
아직 AOP에 대해서 제대로 공부하지 않았기에 이해하기 어려운 부분도 존재했지만, 동작 방식과 과정에 대해서 자세하게 바라볼 수 있었고, 앞으로 @Transactional
을 사용하면서 남발하기 보다 어떻게 활용해야 효율적으로 활용할 수 있을지 고민하며 사용해야겠다.