Spring - @Transactional 어노테이션과 동작 원리

박민수·2024년 6월 13일

Spring

목록 보기
44/46
post-thumbnail

개요

Spring Framework는 자바 개발자에게 다양한 기능을 제공하며, 그 중에서도 데이터베이스 트랜잭션 관리를 손쉽게 할 수 있도록 도와주는 @Transactional 어노테이션이 있다. 이 글에서는 @Transactional의 의미와 이를 사용하여 트랜잭션을 관리하는 방법, 그리고 내부적인 동작 원리에 대해 살펴보고자 한다.

@Transactional이란?

@Transactional 어노테이션은 Spring에서 제공하는 트랜잭션 관리 어노테이션으로, 메서드나 클래스에 적용하여 해당 범위 내에서 실행되는 데이터베이스 작업들이 하나의 트랜잭션으로 처리되도록 한다. 이 어노테이션을 사용하면 코드의 간결성을 유지하면서도 트랜잭션 관리 기능을 쉽게 적용할 수 있다.

@Transactional 사용 방법

기본 사용법

@Transactional 어노테이션은 클래스나 메서드에 붙여 사용할 수 있다. 클래스에 붙이는 경우, 해당 클래스의 모든 public 메서드에 트랜잭션이 적용되고, 메서드에 붙이는 경우, 해당 메서드에만 트랜잭션이 적용된다.

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class MyService {

    @Transactional
    public void performTransaction() {
        // 데이터베이스 작업 코드
    }
}

세부 설정

Transactional 어노테이션은 다양한 속성을 제공하여 트랜잭션의 동작 방식을 세부적으로 설정할 수 있다.

  • propagation: 트랜잭션의 전파 방식을 설정한다. 기본값은 REQUIRED로, 현재 트랜잭션이 존재하면 그 트랜잭션을 사용하고, 없으면 새로 생성한다.
  • isolation: 트랜잭션의 격리 수준을 설정한다. 기본값은 DEFAULT로, 데이터베이스의 기본 격리 수준을 따른다.
  • timeout: 트랜잭션의 제한 시간을 설정한다. 기본값은 제한 시간이 없다.
  • readOnly: 트랜잭션을 읽기 전용으로 설정한다. 기본값은 false이다.
  • rollbackFor: 지정한 예외가 발생하면 롤백을 수행한다.
  • noRollbackFor: 지정한 예외가 발생해도 롤백을 수행하지 않는다.
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class MyService {

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, timeout = 30, readOnly = false, rollbackFor = Exception.class)
    public void performTransaction() {
        // 데이터베이스 작업 코드
    }
}

@Transactional의 동작 원리

@Transactional 어노테이션이 적용된 메서드는 Spring의 AOP(Aspect-Oriented Programming) 기능을 통해 트랜잭션 관리가 이루어진다. 이를 이해하기 위해 내부 동작 과정을 살펴보자.

AOP와 프록시 패턴

Spring은 @Transactional이 붙은 메서드를 호출할 때, 해당 메서드를 프록시 객체로 감싼다. 프록시 객체는 메서드 호출 전후에 트랜잭션을 시작하고 종료하는 역할을 한다. Spring은 JDK 동적 프록시나 CGLIB 프록시를 사용하여 이 작업을 수행한다.

  1. 메서드 호출 전: 프록시 객체는 트랜잭션을 시작한다. 이 때, 기존 트랜잭션이 존재하는지 확인하고, 전파 속성에 따라 트랜잭션을 새로 시작하거나 기존 트랜잭션에 참여한다.
  2. 메서드 실행: 실제 비즈니스 로직이 실행된다.
  3. 메서드 호출 후: 프록시 객체는 트랜잭션을 종료한다. 정상적으로 메서드가 실행되면 커밋하고, 예외가 발생하면 롤백한다.

PlatformTransactionManager

Spring은 다양한 트랜잭션 매니저를 지원합니다. 대표적으로 DataSourceTransactionManager, JpaTransactionManager 등이 있으며, 이는 PlatformTransactionManager 인터페이스를 구현한다. @Transactional 어노테이션이 적용된 메서드가 호출되면, Spring은 적절한 트랜잭션 매니저를 통해 트랜잭션을 관리한다.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;

@Configuration
public class TransactionManagerConfig {

    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

결론

Spring의 @Transactional 어노테이션은 데이터베이스 트랜잭션 관리를 간편하게 해주는 강력한 도구이다. 이를 통해 트랜잭션의 시작, 커밋, 롤백 등을 자동으로 처리할 수 있으며, 다양한 속성을 통해 트랜잭션의 동작 방식을 세부적으로 설정할 수 있다. 내부적으로는 AOP와 프록시 패턴을 사용하여 트랜잭션을 관리하며, PlatformTransactionManager를 통해 다양한 트랜잭션 매니저를 지원한다.

profile
안녕하세요 백엔드 개발자입니다.

0개의 댓글