• 티스토리 홈
starryeye
  • 프로필사진
    starryeye
    • 분류 전체보기 (189)
      • C++ (17)
      • Java (24)
      • OOP (5)
      • Spring Reactive Stack (12)
        • Reactive Streams (3)
        • Netty (4)
        • Reactor (1)
        • Webflux (3)
        • DB, Cache 연동 (1)
      • Spring (90)
        • Core (17)
        • MVC (33)
        • Client (2)
        • Security (4)
        • DB, Cache 연동 (33)
      • DataBase (12)
        • RDBMS (2)
        • NoSQL (10)
      • Message Broker (6)
      • Web (4)
      • Network (4)
      • 대규모 시스템 설계 (15)
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
  • 최근 댓글
      등록된 댓글이 없습니다.
    • 최근 공지
        등록된 공지가 없습니다.
      # Home
      # 공지사항
      #
      # 태그
      # 검색결과
      # 방명록
      • Spring Transaction 2
        2022년 09월 22일
        • starryeye
        • 작성자
        • 2022.09.22.:26
        반응형

        트랜잭션 AOP 주의사항에 대해 알아보자.

         

        1. 동일 클래스에서 내부 @Transaction 메서드 호출

        @Component
        class Service {
        
            @Transaction
            public void A() {
                
            }
            
            public void B() {
                A();
            }
        }
        
        @Component
        @RequiredArgsConstructor
        class Controller {
            
            private final Service s;
            
            public void X() {
                s.A();
            }
            
            public void Y() {
                s.B();
            }
        }

        Service 클래스에서 A() 메서드에 @Transaction 어노테이션이 적용되어있다.

        B() 메서드는 @Transaction 어노테이션이 적용되어 있지 않고 내부에서 A()를 호출하고 있다.

        Controller 클래스에서 Service 클래스를 참조하고 있다.

        Service 클래스는 @Transaction 어노테이션이 존재하므로

        스프링 컨테이너에 트랜잭션 프록시 객체가 등록되고..

        Controller 클래스에 의존성 주입이 될 때 트랜잭션 프록시 객체가 주입된다.

         

        Controller 클래스에서..

        X()를 호출할 경우..

        -> Service 클래스 트랜잭션 프록시 객체의 A() 메서드가 호출되며..

        -> A() 메서드에는 @Transaction 어노테이션이 적용되어 있으므로 트랜잭션이 적용된다.

        -> 트랜잭션 적용 후, 실제 Service 객체 인스턴스의 A() 메서드를 호출한다.

         

        Controller 클래스에서..

        Y()를 호출할 경우..

        -> Service 클래스 트랜잭션 프록시 객체의 B() 메서드가 호출되며..

        -> B() 메서드에는 @Transaction 어노테이션이 적용되어 있지 않으므로 트랜잭션이 적용되지 않는다.

        -> 실제 Service 객체 인스턴스의 B() 메서드를 호출한다.

        -> B() 메서드에서 A() 메서드를 호출한다.

        이 경우, this.A()이고, 트랜잭션 프록시 메서드가 호출된 게 아닌,

        실제 객체에서 단순 자신 메서드 호출이므로 트랜잭션이 적용되지 않는다.

        -> 정리하자면, 내부 호출은 프록시를 거치지 않으며 트랜잭션을 적용할 수 없다.

         

        <해결>

        -> A() 메서드와 B() 메서드를 클래스 자체를 분리하면 가장 간단하게 해결 가능.

         

         

        2. Public 메서드만 트랜잭션이 적용된다.

        private, protected, default 에는 트랜잭션이 적용되지 않는다.

        -> 하지만.. 트랜잭션 프록시는 만들어진다.

        -> 예외도 없고 트랜잭션 적용만 무시된다.

         

         

        3. 스프링 초기화 시점에는 트랜잭션 AOP가 적용 안될 수 도 있다.

         

        어떤 메서드(초기화 코드)에..

        @PostConstruct, @Transaction 두 어노테이션을 적용하면..

        해당 메서드는 트랜잭션이 적용되지 않는다.

        -> 초기화 코드가 먼저 호출 된 후, 트랜잭션 AOP가 적용되기 때문

         

        <해결>

        @EventListener(value = ApplicationReadyEvent.class) 와 @Transaction 을 같이 사용하자.

        -> 트랜잭션 AOP를 포함한 스프링 컨테이너가 완전히 생성되고

        -> 해당 어노테이션이 붙은 메서드를 호출 해준다.

        반응형

        'Spring > DB, Cache 연동' 카테고리의 다른 글

        Spring Transaction 4  (0) 2022.09.28
        Spring Transaction 3  (0) 2022.09.22
        Spring Transaction 1  (0) 2022.09.22
        JPA 찍먹 1  (1) 2022.09.09
        MyBatis 1  (0) 2022.08.23
        다음글
        다음 글이 없습니다.
        이전글
        이전 글이 없습니다.
        댓글
      조회된 결과가 없습니다.
      스킨 업데이트 안내
      현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
      ("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
      목차
      표시할 목차가 없습니다.
        • 안녕하세요
        • 감사해요
        • 잘있어요

        티스토리툴바