트랜잭션 AOP 사용시 주의사항 - 내부호출.

Jobmania·2023년 9월 19일
0

스프링 

목록 보기
5/5

💚트랜잭션 AOP 사용시 주의 사항

static class CallService{
        public void external(){
            // 외부에서 호출하는거양ㅇ~
            log.info("call external");
            printTxInfo();
            internal(); // this. 나 자신의 인스턴스 주소!!
        }

        @Transactional
        public void internal(){
            log.info("call internal");
            printTxInfo();
        }
 }

@Transactional이 하나라도 있다면 스프링 컨테이너는 프록시 객체를 컨테이너에 등록한다.

그러나

트랜잭션이 적용되지 못했음.

트랜잭션이 적용되지 않은 이유!!

1.external()은 트랜잭션이 적용 x , 적용하지 않고 실제 service.external() 사용.
2. ( 5 번 ) 에서 실제 서비스 적용된다., 트랜잭션이 적용된 프록시가 아니라!
생략된 (this) => 나 자신의 인스턴스의 주소 (실제 대상 객체)를 불러와 트랜잭션 aop가 적용되지 않는 상태를 들고옴..

그래서

💥 별도의 클래스로 분리

@Slf4j
    @RequiredArgsConstructor
    static class CallService{
        private final InternalService internalService;
        public void external(){
            log.info("call external");
            printTxInfo();
            internalService.internal(); // 내부호출에서 외부 호출로

        }

        private void printTxInfo(){
            boolean txActive = TransactionSynchronizationManager.isActualTransactionActive();
            log.info("tx active={}", txActive);
        }
    }


    static class InternalService{
        @Transactional
        public void internal(){
            log.info("call internal");
            printTxInfo();
        }

        private void printTxInfo(){
            boolean txActive = TransactionSynchronizationManager.isActualTransactionActive();
            log.info("tx active={}", txActive);

        }
    }

💦 클래스 접근 레벨이 public 이여만 @Transactional 적용된다.


-> 트랜잭션이 적용 되지 않았음

profile
HelloWorld에서 RealWorld로

0개의 댓글