lty's Blog

Spring @Transactional 원리 본문

웹개발/Spring

Spring @Transactional 원리

LIMTAEYANG 2026. 1. 6. 23:36

1. 트랜잭션이란? 

여러 개의 작업을 하나의 논리적인 작업 단위로 묶는 것 

2. 트랜잭션의 목적 (ACID)

Atomicity (원자성) 전부 성공 OR 전부 실패 
Consistency (일관성) 데이터 무결성 유지
Isolation (격리성) 트랜잭션 간 간섭 방지
Durability (지속성) 커밋된 데이터는 유지 

 

3. @Transactional 동작 원리 

@Transactional 어노테이션은 AOP Proxy 기반으로 동작하여 실제 객체 대신 프록시 객체가 빈으로 등록되고 프록시가 원본 메서드 호출을 가로채 트랜잭션을 제어한다. 

 

  1. 프록시 객체의 메서드 실행
  2. TransactionInterceptor 실행 (프록시가 트랜잭션 시작/종료를 가로챔)
  3. PlatformTransactionManager 호출
  4. 실제 서비스 메서드 실행
  5. 예외 여부에 따라 commit / rollback 실행
// 프록시 객체 생성 
TransactionStatus txStatus = transactionManager.getTransaction(new DefaultTransactionDefinition());

try {
    // 비즈니스 로직 (원본 호출 함수)
    transactionManager.commit(txStatus);
} catch (Exception e) {
    transactionManager.rollback(txStatus);
}

 

쉽게말해 @Transactional은 이 코드를 AOP기반으로 자동 생성 하여 동작 

복제 Proxy 종류 

1. JDK Dynamic Proxy : 인터페이스 기반 프록시 (대상 클래스가 인터페이스를 구현하고 있을 때 동작)

public interface UserService {
    void save();
}

@Service
public class UserServiceImpl implements UserService {
    
    // 실제 클래스가 아니라 인터페이스를 구현한 프록시 객체 생성
    // InvocationHandler.invoke() 함수 시작 전 실행 
    @Transactional
    public void save() {}
}

 

2. CGLIB Proxy : 클래스 기반 (인터페이스 없음 OR ProxyTargetClass=True - 강제사용 시 옵션 추가) 

* CGLIB : 런타임에 바이트 코드를 생성해서 기존 클래스를 상속한 프록시 클래스를 만드는 라이브러리

@Service
public class OrderService {

    @Transactional
    public void order() {}
}

 

CGLIB 자동 사용하며 원본 클래스를 상속한 자식 클래스를 생성 하여 실행 

 (트랜잭션이 필요한 메서드를 오버라이드 하여 상속, 오버라이드 불가한 경우, 내부호출 시 사용할 수 없다.)

@Transactional 사용할 수 없는 경우

final class 상속 불가
final method 오버라이드 불가
private method 오버라이드 불가
내부 호출 (자기자신 호출) 프록시 미경유
Comments