@Transactional 동작 과정에 대해 알아보자

이현지·2023년 7월 25일
0

@Transactional 이란?

Spring 의 핵심 개념 중 하나인 AOP 기술을 활용한 예 중 하나로, Spring에선 Spring AOP 방식으로 동작한다.
메서드나 클래스에 어노테이션을 붙이면 해당 메서드 또는 클래스의 작업들을 하나의 트랜잭션으로 관리하겠다는 의미이다.
그렇다면 AOP 가 무엇일까? AOP 에 대해 잠시 알아보자.

AOP란?

Aspect Object Programming 으로 관점 지향 프로그래밍 방법이다. 관심사의 분리라고도 말하며, 기존 OOP의 단점을 보완한 방식이다. 여러 클래스 사이에 공통적으로 포함되어있는 로그, 트랜잭션, 예외 처리 코드등 부가 기능을 비지니스 로직과 분리하여 관리하는 방식이다. 그로 인해 비지니스 로직은 비지니스 로직에 초점을 맞출 수 있고, 코드의 중복을 줄일 수 있으며, 유지 보수를 원활하게 할 수 있다.

AOP 에 대해 간단히 알아보았으니 본격적으로 @Transactional 의 동작 과정에 대해 알아보자

@Transactional 동작 과정

@Transactional 은 Spring AOP 방식으로 동작한다. 그리고 Spring AOP 방식은 프록시 패턴을 활용한다. 프록시 패턴을 활용하는 이유는 Target 에 코드를 추가하지 않고, 부가 기능을 추가할 수 있기 때문이다.

  1. 먼저 @Transactional 어노테이션이 적용된 메서드를 호출하면, Spring 은 해당 메서드를 감싸는 동적 프록시 객체를 생성한다.

    동적 프록시 생성 방법 : JDK Proxy 와 CGLIB (아래 참고)

  1. 생성된 동적 프록시는 메서드가 호출될 때 중간에 가로채서 트랜잭션을 시작하고, 트랜잭션 컨텍스트를 실행한다.(트랜잭션을 실행하는 코드는 JDBC 와 동일)
  2. 트랜잭션을 컨텍스트를 실행한 후 원본 메서드를 호출하여, 비지니스 로직을 실행한다.
  3. 메서드 내에서 데이터베이스 작업 등의 트랜잭션 처리가 발생할 때, 프록시는 이를 트랜잭션 컨텍스트에 위임해서 실행한다.

위 설명을 그림으로 표현하면 아래 그림과 같다고 볼 수 있다.

JDBC 트랜잭션 방법

JDBC 에서 트랜잭션을 실행하는 코드이다. @Transactional 도 내부적으론 아래와 같은 코드를 실행한다.

Connection connection = dataSource.getConnection();
 
try (connection) {
    connection.setAutoCommit(false);
    
    // DB 작업
    
    connection.commit();
} catch (SQLException e) {
    connection.rollback();
}

동적 프록시 객체 생성 방법

동적 프록시 객체를 생성하는 방법은 2가지가 있다. Spring 은 JDK Proxy 를 기본으로 사용하고, Spring Boot 는 CGLib 방식을 기본으로 사용한다.

JDK Proxy

Target 의 상위 인터페이스를 상속 받아 프록시를 생성하며 다음과 같은 특징을 가진다.

  • 프록시를 생성할 클래스가 인터페이스를 구현하지 않고, 구체 클래스에 의존한다면 해당 클래스를 찾을 수 없어 런타임 에러가 발생
  • 인터페이스를 반드시 구현해야하며, 리플렉션을 사용한 방식으로 비용이 더 비싸다
  • Spring default

CGLIB(Code Generation Library) Proxy

Target 을 상속 받아 프록시를 생성하며 다음과 같은 특징을 가진다.

  • 프록시를 생성할 클래스가 인터페이스를 구현하고 있지 않은 경우
  • 클래스의 바이트 코드를 조작하여 서브클래스를 동적으로 생성하는 라이브러리
  • 인터페이스를 구현할 필요가 없고, 구체 클래스에 의존하므로 런타임 에러가 발생할 확률이 적음
  • Spring Boot default

References

https://blogshine.tistory.com/291
https://jeong-pro.tistory.com/228
https://minkukjo.github.io/framework/2021/05/23/Spring

profile
Backend Developer👩‍💻

1개의 댓글

comment-user-thumbnail
2023년 7월 25일

이런 유용한 정보를 나눠주셔서 감사합니다.

답글 달기