Spring에서 트랜잭션은 어떻게 동작할까?

David Lee·2023년 10월 22일
0
post-thumbnail

Spring Framework에서 트랜잭션의 동작방식과 @Transactional의 기능에 대해 살펴봅니다.

포스트를 작성하게 된 계기는...

데브코스에서 @Transactional 어노테이션에 대한 강의를 듣게 되었다. 지금까지 프로젝트를 진행하면서 @Transactional 어노테이션을 사용해보긴 했지만, 트렌젝션으로 메소드를 처리하기 위해서는 사용해야하는 어노테이션이다! 정도만 알고 사용했었다. 강의를 듣다 보니 내가 지금까지 @Transactional을 사용하면서 잘못 사용한 부분도 존재하고 생각했던 개념과 좀 다른 부분이 있는것 같아서 이참에 Spring에서 트랜잭션에 대해 자세히 알아보자! 라는 생각에 포스트를 작성하게 되었다.

Spring Framework에서 트랜잭션의 구현

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 관점을 적용했다. 비즈니스 로직을 작성한 후 트랜잭션 선언을 하면 트랜잭션이 구현되도록 만들어 놓았다는 것인데, 그렇다면 메서드를 호출했을때 어떤 방식으로 동작이 될까?

Spring에서 선언적 트랜잭션의 동작방식

Conceptual View of Calling a Method on a transactional proxy
스프링에서 제공하는 트랜잭션 호출의 개념도를 살펴보면 AOP 프록시를 활용해서 활성화되기 시작한다는 것을 볼 수 있다.
프록시 내부에 Target Method의 실행 전후로 지정한 Custom Advisior가 실행되고, Transaction Advisior가 트랜잭션에 대한 Rollback or Commit을 결정하고 Proxy 객체를 통해 반환되는 형식으로 동작이 진행됨을 확인할 수 있다. 그렇다면 트랜잭션이 어떤 경우에 Commit될지 Rollback될지 어떻게 결정할 수 있을까??

@Transactional 살펴보기

트랜잭션을 지정하기위해 @Transactional을 사용하면 기본적으로 아래와 같이 세팅이된다.

  • 트랜젝션은 읽고 쓰기가 가능하다.
  • 트랜잭션의 Isolation level은 ISOLATION_DEFAULT이다.
  • 트랜잭션의 시간 초과값은 기존 트랜잭션 시스템을 따라가며 트랜잭션 시스템이 시간 초과를 지원하지 않으면 none이다.
  • RunetimeExceptionError가 발생하면 Rollback을 수행한다. checked Exception에 대해서는 Rollback을 수행하지 않는다.
  • Propagation은 PROPAGATION_REQUIRED를 따른다.

기본적으로 트랜잭션은 RuntimeExceptionError 발생시 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로 전달
    함으로써 Commit, Rollback의 조건을 정할 수 있다.

더욱 자세하게 트랜잭션을 설정하고 싶다면 @Transactional Settings을 참고하자!

결론

Spring은 트랜잭션을 AOP 형식의 프록시로 만들고 관리한다는 점이 공부를 하면서 알게 된 가장 중요한 부분인 것 같다.
아직 AOP에 대해서 제대로 공부하지 않았기에 이해하기 어려운 부분도 존재했지만, 동작 방식과 과정에 대해서 자세하게 바라볼 수 있었고, 앞으로 @Transactional을 사용하면서 남발하기 보다 어떻게 활용해야 효율적으로 활용할 수 있을지 고민하며 사용해야겠다.

출처

profile
쌓아가기

0개의 댓글

관련 채용 정보