Spring Transaction

MONA·2025년 3월 27일

나혼공

목록 보기
63/92

Transaction

DB 작업을 하나의 단위로 묶어 성공하면 commit, 실패하면 rollback하는 기능

Spring Transaction은 AOP 기반이다
-> 메서드 실행 전/후에 트랜젝션 관련 처리를 자동으로 끼워 넣음

AOP (Aspect-Oriented Programming)

관점 지향 프로그래밍
코드의 공통 관심사를 분리해서 핵심 비즈니스 로직과 부가 로직(로그, 보안, 트랜젝션 등)을 나누는 프로그래밍 기법

여러 곳에서 반복되는 부가 기능을 빼서 한곳에서 따로 처리하는 방법.
핵심 로직은 그대로 두고, 공통되는 관심사(Aspect)를 따로 분리해서 깔끔한 코드를 만들 수 있게 한다

분리 전 코드- 결제 + 로깅

public void pay() {
    System.out.println("[로그] 결제 시작");
    // 결제 처리 로직
    System.out.println("[로그] 결제 완료");
}

분리 후 코드- 결제/로깅

public void pay() {
    // 결제 처리 로직만 집중
}
@Aspect
public class LogAspect {
    @Before("execution(* com.example.service.*.*(..))")
    public void logBefore() {
        System.out.println("[Log] 메서드 실행 전");
    }

    @After("execution(* com.example.service.*.*(..))")
    public void logAfter() {
        System.out.println("[Log] 메서드 실행 후");
    }
}

pay()는 결제 로직만 담당하고, 로그는 따로 빼서 LogAspect 클래스에서 자동으로 실행되게 설정.

AOP 주요 용어

용어의미
Aspect공통 기능(로그, 트랜젝션 등)을 정의한 모듈
Advice언제 실행할지를 정의(before, after, around 등)
JoinPointAdvice가 끼어들 수 있는 지점(메서드 실행 지점 등)
Pointcut어떤 JoinPointAdvice를 적용할지 지정
WeavingAdvice를 실제 코드에 적용하는 과정(런타임 또는 컴파일 타임 등)

언제 AOP를 사용할까?

  • 트랜젝션 처리(@Transacntional)
  • 로깅(@LogExecution)
  • 보안 검사(@Secured)
  • 성능 측정
  • 인증/권한 처리
  • 캐싱

-> 비즈니스 로직과 상관없는 공통 관심사 분리 시 사용

Spring에서 AOP가 어떻게 작용할까

  • 클래스나 메서드 호출을 감싸는 프록시 객체를 만든다
  • Before -> 메서드 실행 -> After 흐름을 자동으로 구성해줌

AOP 기반 트랜젝션 처리 흐름

간단히

  1. 트랜젝션 대상 메서드 호출
  2. AOP proxy가 가로챔(Proxy 객체)
  3. 트랜젝션 시작(@Transactional)
  4. 실제 메서드 실행
  5. 예외 여부 확인 -> 예외 없을 시 commit, 발생 시 rollback
  6. 트랜젝션 정리(자원 반환)

자세히

  1. 프록시 객체가 메서드를 가로챔

    • @Transactional이 붙은 메서드를 프록시로 감싼다
    • 이 프록시 객체는 AOP 방식으로 메서드 실행 전/후에 트랜젝션을 시작하거나 종료함
    
    @Service
    public class OrderService {
        @Transactional
        public void placeOrder() {
            // 실제 메서드 내용
        }
    }
    - `OrderService` 내부적으로 프록시가 생성되어 실행 흐름을 통제함
  2. 트랜젝션 시작(TransactionManager 사용)

    • 프록시는 TransanctionManager를 통해 DB 커넥션을 얻고, 트랜젝션을 시작함
    connection.setAutoCommit(false); // JDBC
  3. 비즈니스 로직 실행

  4. 정상 종료 Or 예외 발생 상황 판단

    4-1. 예외가 없을 시 -> commit() 실행, 변경 사항 DB 반영
    4-2. 예외 발생 시 -> rollback() 실행, 이전 상태로 되돌림

    • Spring은 기본적으로 RuntimeException이나 Error만 롤백함(Checked Exception은 자동 롤백하지 않음, 필요시 rollbackFor 옵션 설정)
    @Transactional(rollbackFor = Exception.class)

Checked Exception

  • 컴파일 시점에 반드시 처리해야 하는 예외. IOException, SQLException 등

  • 반드시 try-catch하거나, throws를 선언해야 함

  • 주로 외부 시스템과의 통신, 입출력, DB 작업 등에서 발생

    Throwable
     ├── Error (JVM 관련, OutOfMemory 등 → 거의 신경 안 씀)
     └── Exception
          ├── Checked Exception (IOException, SQLException 등)
          └── RuntimeException (NullPointerException, IllegalArgumentException 등)
  1. 트랜젝션 종료 및 자원 정리

    • 커넥션 반환
    • 트랜젝션 정리

주의

  1. 자기 자신을 호출하는 경우

    • 같은 클래스 내에서 this.transactionMethod()는 프록시를 타지 않아서 트랜젝션 안 먹음.
  2. public 메서드에만 적용됨

  3. 프록시 미적용 시 주의

    • AOP 적용 안되면 트랜젝션도 동작 안함(ex: @Component 누락)
  4. 예외 처리 try-catch 후 무시할 경우

    • 예외가 밖으로 나가지 않으면 트랜젝션이 rollback되지 않음
profile
고민고민고민

0개의 댓글