트랜잭션 AOP

wangjh789·2022년 8월 14일
0

[Spring] 스프링-DB-1

목록 보기
11/15

프록시를 사용하면 트랜잭션을 처리하는 객체와 비즈니스 로직을 처리하는 서비스 객체를 명확하게 분리할 수 있다.

스프링 AOP를 사용하기 위해선 프록시를 만들 객체가 스프링 빈에 등록이 되야한다.

    @TestConfiguration
    static class TestConfig{
        @Bean
        DataSource dataSource() {
            return new DriverManagerDataSource(URL, USERNAME, PASSWORD);
        }

        @Bean
        PlatformTransactionManager transactionManager() {
            return new DataSourceTransactionManager(dataSource());
        }

        @Bean
        MemberRepositoryV3 memberRepositoryV3(){
            return new MemberRepositoryV3(dataSource());
        }

        @Bean
        MemberServiceV3_3 memberServiceV3_3() {
            return new MemberServiceV3_3(memberRepositoryV3());
        }
    }

이제껏 했던 Test는 직접 트랜잭션매니저(PlatformTransactionManager)를 이용한 방법이기 때문에 bean과는 무관한 테스트 였다. 스프링 AOP를 사용한 @Transactional가 붙은 서비스 로직을 사용하기 위해선 @SpringBootTest를 붙여야 한다.

AOP 적용 확인

    @Test
    void AppCheck() {
        log.info("memberService class = {}", memberService.getClass());
        log.info("memberRepository class = {}", memberRepository.getClass());
        assertThat(AopUtils.isAopProxy(memberService)).isTrue();
    }
memberService class = class hello.jdbc.service.MemberServiceV3_3$$EnhancerBySpringCGLIB$$e2abb52
memberRepository class = class hello.jdbc.repository.MemberRepositoryV3

MemberServiceV3_3$$EnhancerBySpringCGLIB -> AOP로 생성된 서비스 계층의 프록시

서비스계층의 프록시는 내부적으로 트랜잭션 매니저를 사용해 트랜잭션을 시작하면서 데이터 소스에서 커넥션을 만든 후, 수동커밋 모드로 만들고 트랜잭션 동기화 매니저에 커넥션을 보관한다.
핵심로직이 수행될 떄는 실제 서비스 객체의 참조값으로 메서드를 호출한다.

선언적 트랜잭션 관리vs 프로그래밍 방식 트랜잭션 관리

  • 선언적 트랜잭션 관리
    @Transactional -> 간단하지만 스프링 컨테이너가 필요하다.
  • 프로그래밍 방식 트랜잭션 관리
    PlatFormTransactionManager를 직접 쓰는 방식
    TransactionTemplate을 사용하는 방식
    -> 코드가 복잡하지만 스프링 컨테이너가 필요없다.
profile
기록

0개의 댓글