[Spring boot] @Transactional 이란?

2025. 4. 8. 17:16·개발 | 프로젝트/Java | Spring

1. 트랜잭션이란?

트랜잭션은 데이터베이스의 상태를 변환시키는 하나의 논리적 작업 단위를 말합니다. 쇼핑몰에서 주문을 처리할 때, 주문 정보 저장, 재고 감소, 결제 처리가 모두 성공해야만 전체 주문이 완료됩니다. 이 세 가지 작업을 하나의 트랜잭션으로 묶어서 처리하면, 중간에 문제가 생겼을 때 모든 작업을 원래대로 되돌릴 수 있습니다.

트랜잭션은 다음 네 가지 특성(ACID)을 가집니다.

  • 원자성(Atomicity): 트랜잭션 내의 모든 작업은 전부 성공하거나 전부 실패합니다.
  • 일관성(Consistency): 트랜잭션이 완료된 후에도 데이터베이스는 일관된 상태를 유지해야 합니다.
  • 격리성(Isolation): 동시에 실행되는 트랜잭션들은 서로 영향을 미치지 않습니다.
  • 지속성(Durability): 트랜잭션이 성공적으로 완료되면, 그 결과는 영구적으로 반영됩니다.

 

2. @Transactional 기본 개념

@Transactional은 말 그대로 트랜잭션(거래)의 경계를 설정해주는 어노테이션입니다.
하나의 작업 단위에서 모든 처리가 성공해야만 커밋되고, 하나라도 실패하면 롤백되어야 하는 경우에 사용합니다.

 

스프링에서는 트랜잭션을 관리하는 두 가지 방법이 있습니다:

  1. 프로그래밍 방식: 직접 코드로 트랜잭션을 시작, 커밋, 롤백하는 방식
  2. 선언적 방식: @Transactional 어노테이션을 사용하는 방식

대부분의 경우 @Transactional 어노테이션을 사용하는 선언적 방식이 더 간편하고 코드도 깔끔해집니다.

 

기본 사용법

 
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserService {
    
    private final UserRepository userRepository;
    
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
    @Transactional
    public void createUser(User user) {
        userRepository.save(user);
        // 이 메서드 내의 모든 데이터베이스 작업은 하나의 트랜잭션으로 처리됩니다.
        // 중간에 예외가 발생하면 모든 변경사항이 롤백됩니다.
    }
}
  • 클래스에 적용: 해당 클래스의 모든 public 메서드에 트랜잭션이 적용됩니다.
  • 메서드에 적용: 해당 메서드만 트랜잭션으로 처리됩니다.

 

3. 주요 속성 알아보기

@Transactional에는 다양한 속성이 있어 트랜잭션 동작을 세밀하게 제어할 수 있습니다.

대표적인 속성들

 
@Transactional(
    propagation = Propagation.REQUIRED,  // 트랜잭션 전파 방식
    isolation = Isolation.DEFAULT,       // 격리 수준
    timeout = 30,                        // 타임아웃(초)
    readOnly = false,                    // 읽기 전용 여부
    rollbackFor = Exception.class,       // 롤백을 발생시킬 예외
    noRollbackFor = NotFoundException.class // 롤백을 발생시키지 않을 예외
)

timeout

트랜잭션의 제한 시간을 초 단위로 설정합니다. 지정한 시간이 지나면 트랜잭션이 자동으로 롤백됩니다.

 

readOnly

트랜잭션을 읽기 전용으로 설정합니다. 이 설정은 다음과 같은 이점이 있습니다:

  • 데이터베이스에 읽기 전용이라는 힌트를 제공해 최적화 가능
  • JPA/Hibernate의 경우 더티 체킹(변경 감지)을 하지 않아 성능 향상
 

rollbackFor / noRollbackFor

기본적으로 스프링은 RuntimeException과 Error가 발생했을 때만 롤백합니다. 하지만 이 속성들을 사용하면 롤백 조건을 직접 지정할 수 있습니다.

 

 

4. @Transactional의 내부 동작 원리

1. 프록시 기반 AOP(관점 지향 프로그래밍)

스프링의 @Transactional은 프록시 기반 AOP를 통해 동작합니다.

  • 스프링이 @Transactional이 붙은 클래스에 대해 프록시 객체를 생성
  • 클라이언트가 메서드를 호출하면 실제 객체가 아닌 프록시 객체가 호출을 가로채서 트랜잭션을 처리함

AOP란?

AOP는 공통 관심 사항(cross-cutting concerns)을 핵심 로직과 분리해서 코드를 깔끔하게 유지할 수 있도록 도와주는 프로그래밍 패러다임입니다.

예: 로깅, 보안 체크, 트랜잭션 처리

 

2. 트랜잭션 처리 흐름

@Transactional이 적용된 메서드가 호출되면 다음과 같은 순서로 처리됩니다.

[호출] → [트랜잭션 시작] → [원본 메서드 실행] → [정상: 커밋 / 예외: 롤백] → [종료]

 

  • 트랜잭션 경계 설정: 프록시는 PlatformTransactionManager를 통해 트랜잭션을 시작합니다.
  • 트랜잭션 속성 적용: @Transactional에 지정된 전파 방식, 격리 수준 등의 속성을 적용합니다.
  • 원본 메서드 호출: 실제 비즈니스 로직이 담긴 원본 메서드를 실행합니다.
  • 예외 처리 및 커밋/롤백 결정:
    • 메서드가 정상적으로 완료되면 트랜잭션을 커밋합니다.
    • 런타임 예외(RuntimeException)가 발생하면 트랜잭션을 롤백합니다.
    • checked 예외(Exception)는 기본적으로 롤백하지 않습니다(rollbackFor 속성으로 변경 가능).

 

1) 트랜잭션 선언 (@Transactional)

개발자가 @Transactional 어노테이션을 메서드나 클래스에 붙이면
스프링은 프록시(Proxy) 객체를 생성하여 원래 객체를 감싸게 됩니다.

@Service
public class UserService {
  
  @Transactional
  public void registerUser(User user) {
    userRepository.save(user);
    logRepository.save(new Log("User created"));
  }
}

 

2) 프록시가 메서드 호출 감지

사용자가 registerUser()를 호출하면 실제 객체가 아니라 프록시 객체가 호출을 가로채 다음 작업을 합니다:

  1. 트랜잭션이 이미 존재하는지 확인
  2. 없다면 새 트랜잭션 시작
  3. 대상 메서드 실행
  4. 정상 종료 → 커밋 / 예외 발생 → 롤백

 

3) 트랜잭션 경계 설정

스프링은 PlatformTransactionManager를 통해 트랜잭션을 실제로 관리합니다.
JPA를 사용할 경우 → JpaTransactionManager가 자동으로 등록됨.

TransactionStatus status = transactionManager.getTransaction(...);
try {
    // 비즈니스 로직 수행
    transactionManager.commit(status);
} catch (Exception e) {
    transactionManager.rollback(status);
}

 

'개발 | 프로젝트 > Java | Spring' 카테고리의 다른 글

[Spring Boot] @Valid 유효성 검사가 되지 않을 때  (0) 2025.05.12
[Spring Boot] GlobalExceptionHandler 예외 처리  (0) 2025.04.06
[Spring Security] UsernamePasswordAuthenticationFilter Authentication Flow  (0) 2025.03.21
[Spring] Spring Security CSS 적용 안되는 오류  (0) 2025.02.27
[Spring] Spring Security  (0) 2025.02.26
'개발 | 프로젝트/Java | Spring' 카테고리의 다른 글
  • [Spring Boot] @Valid 유효성 검사가 되지 않을 때
  • [Spring Boot] GlobalExceptionHandler 예외 처리
  • [Spring Security] UsernamePasswordAuthenticationFilter Authentication Flow
  • [Spring] Spring Security CSS 적용 안되는 오류
seulll
seulll
개인 공부 / 정리 블로그입니다
  • seulll
    seulll
    seulll
  • 전체
    오늘
    어제
    • 분류 전체보기 (333) N
      • 코딩테스트 (227) N
        • programmers (python) (156)
        • 백준 (python) (69) N
      • 자료구조 | 알고리즘 (14)
      • 개발 | 프로젝트 (19) N
        • Python (4)
        • Java | Spring (7)
        • Android (4)
        • Unity (3)
        • API (4)
      • CS (15)
        • Network (5)
        • SQL (2)
        • OS (4)
      • 데이터 분석 (14)
      • 기타 (13)
  • 블로그 메뉴

    • 홈
    • 태그
    • 글쓰기
    • 설정
  • 링크

    • GitHub
  • 인기 글

  • 태그

    Boxplot
    모델 성능 평가
    train_test_split
    파이썬
    백엔드 개발자 역량
    solving environment
    코딩테스트
    대입 표현식
    2 x n 타일링
    오블완
    confusion matrix
    바다코끼리
    카카오맵
    카카오맵 api
    API
    백엔드
    asterisk
    Greedy
    프로그래머스
    박스플롯
    Python
    데이터분석
    백엔드 개발자
    kakao map api
    웹크롤링
    프렌즈4블록
    오차행렬
    그리디 알고리즘
    티스토리챌린지
    야근 지수
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
seulll
[Spring boot] @Transactional 이란?
상단으로

티스토리툴바