스프링/6. 스프링 DB-2

40. 스프링 트랜잭션 테스트

sdafdq 2023. 10. 14. 19:40

트랜잭션 가져왔다.

먼저, 테스트 환경에서 로그 보기 위해

testAnnotationProcessor 'org.projectlombok:lombok' 
testImplementation 'org.projectlombok:lombok' 

build.gradle에 추가,

 

그 다음 application.properties에

logging.level.org.springframework.transaction.interceptor = TRACE

로그 중 트랜잭션의 것을 인터셉트 해 오는데 TRACE 레벨을 인터셉트 해 옴

 

@Slf4j
@SpringBootTest
public class TxBasicTest {

    @Autowired
    BasicService basicService;

    @Test
    void proxyCheck(){
        log.info("aop class={}", basicService.getClass());
        Assertions.assertThat(AopUtils.isAopProxy(basicService)).isTrue();
    }

    @Test
    void txTest(){
        basicService.tx();
        basicService.nonTx();
    }


    @TestConfiguration
    static class TxApplyBasicConfig{
        @Bean
        BasicService basicService(){
            return new BasicService();
        }
    }

    @Slf4j
    static class BasicService{
        @Transactional
        public void tx(){
            log.info("call tx");
            boolean txActive = TransactionSynchronizationManager.isActualTransactionActive();
            log.info("tx active = {}", txActive);
        }

        public void nonTx(){
            log.info("call nonTx");
            boolean txActive = TransactionSynchronizationManager.isActualTransactionActive();
            log.info("tx active = {}", txActive);
        }
    }
}

테스트 코드.

먼저 @Transactional이 스프링부트에서 자동으로 트랜잭션 할 수 있는 환경 넣어주는 거니까,

@SpringBootTest 해서 스프링 환경으로 테스트 한다고 해야 함.

 

대충 클래스 BasicService 만들어서

tx는 @Transactional 붙이고 nonTx는 안 붙여서 

TransactionSynchronizationManager.isActualTransactionActive()

이거 하면 직역은 트랜잭션 동기 매니저 . 실제로 트랜잭션 활성중인지.

활성중이면 true, 아니면 false

 

그거 그냥

@Test

txTest()

해서 직접 로그 확인.

 

2023-10-14T19:36:10.734+09:00 TRACE 34568 --- [main] o.s.t.i.TransactionInterceptor : Getting transaction for [hello.springtx.apply.TxBasicTest$BasicService.tx]
2023-10-14T19:36:10.734+09:00  INFO 34568 --- [ main] h.s.apply.TxBasicTest$BasicService : call tx
2023-10-14T19:36:10.734+09:00  INFO 34568 --- [  main] h.s.apply.TxBasicTest$BasicService: tx active = true
2023-10-14T19:36:10.735+09:00 TRACE 34568 --- [ main] o.s.t.i.TransactionInterceptor : Completing transaction for [hello.springtx.apply.TxBasicTest$BasicService.tx]


2023-10-14T19:36:10.737+09:00  INFO 34568 --- [main] h.s.apply.TxBasicTest$BasicService       : call nonTx
2023-10-14T19:36:10.737+09:00  INFO 34568 --- [main] h.s.apply.TxBasicTest$BasicService       : tx active = false

 

딱 보면 이제

@Transactional 붙인 건 true로 나옴.

Getting transaction 뭐 트랜잭션 얻는다, 트랜잭션 완료한다 이런 건 인터셉터 저거  우리가 인터셉터 해온다고 한 거 application.properties에서

 

참고로 BasicService 저거 내부에 하나라도 프록시 될 요소 가지고 있으면 무조건 프록시 객체로 들어옴.

하긴 그래야 맞는 거기도 함. 뭐 프록시로 트랜잭션 처리해야 할 객체, 그냥 처리 할 객체 따로 만들 이유도 없고.

 

프록시 자체가 쫌 뭐랄까

BasicService 상속 받은 다음에 

BasicService를 필드로 가지고 있는 그런 느낌인 듯?