Spring AOP

Spring AOP는 프록시 패턴으로 트랜잭션 제어 코드를 비즈니스 로직에 동적으로 주입한다. @Transactional이 선언된 빈이 컨테이너에 등록될 때, Spring은 실제 객체를 감싸는 프록시 객체를 자동으로 만들어 등록한다.[1] 이 프록시가 Spring Transaction의 선언적 트랜잭션이 서 있는 토대이며,[1:1] Transaction Propagation의 전파 속성이 이 프록시 경계 안에서 적용된다고 연결하는 것은 이 page의 해석이다.

프록시가 트랜잭션을 여는 흐름

sequenceDiagram
    autonumber
    actor Client as Client (Controller 등)
    participant Proxy as AOP Proxy
(트랜잭션 경계) participant TxManager as PlatformTransactionManager participant Target as Target Service
(비즈니스 로직) participant DB as DB Note over Client, Proxy: 외부 호출일 때만 Proxy 작동 Client->>Proxy: 메서드 호출 Proxy->>TxManager: 트랜잭션 시작 (begin) TxManager->>DB: SET autocommit = false Proxy->>Target: 실제 타겟 메서드 위임 alt 정상 종료 Target-->>Proxy: 리턴 Proxy->>TxManager: Commit TxManager->>DB: COMMIT else Unchecked 예외 Target-->>Proxy: Throw RuntimeException Proxy->>TxManager: Rollback TxManager->>DB: ROLLBACK end Proxy-->>Client: 결과 반환

내부 호출(Self-Invocation)에서 트랜잭션이 사라지는 이유

관련

출처

테스트 질문


  1. Transaction.md — "스프링의 선언적 트랜잭션은 **Spring AOP(관점 지향 프로그래밍)**를 바탕으로 동작합니다. 구체적으로는 프록시 패턴을 사용하여 트랜잭션 제어 코드를 비즈니스 로직에 동적으로 주입합니다."(L44), "@Transactional이 선언된 빈(Bean)이 컨테이너에 등록될 때, 스프링은 실제 객체를 감싸는 프록시 객체(Proxy)를 자동으로 만들어 등록합니다."(L47) ↩︎ ↩︎

  2. Transaction.md — "클라이언트가 메서드를 호출하면 프록시 객체의 메서드가 대신 먼저 호출되며, 내부의 PlatformTransactionManager를 통해 DB 트랜잭션을 시작(begin)합니다.", "트랜잭션이 열린 상태에서 실제 Target 객체의 비즈니스 로직 메서드를 실행합니다.", "메서드가 정상 종료되면 트랜잭션을 커밋(Commit)합니다." ↩︎ ↩︎ ↩︎

  3. Transaction.md — "프록시 방식의 특성상, 외부 객체가 프록시를 통해 메서드를 호출할 때만 AOP 트랜잭션이 작동합니다.", "클래스 내부에서 @Transactional이 없는 메서드가 동일 클래스 내의 다른 @Transactional 메서드를 직접 호출(this 호출)하는 경우, 프록시를 거치지 않고 실제 객체의 레퍼런스를 직접 참조하므로 트랜잭션이 적용되지 않습니다." ↩︎ ↩︎

  4. Transaction.md — "가장 권장되는 방법은 트랜잭션이 필요한 비즈니스 단위를 별도의 클래스(서비스 빈)로 분리하여 외부 호출 구조로 변경하는 것입니다.", "스프링의 의존성 셀프 주입(Self-Injection)을 활용하여 내부 호출을 회피합니다." ↩︎