스프링 - 트랜잭션 AOP

박찬우·2024년 2월 2일

스프링 DB

목록 보기
17/53

트랜잭션 AOP

  • 트랜잭션 관련 처리기능과 비즈니스 로직을 분리하기 위해 프록시를 사용
  • 스프링에서는 @Transactional 애노테이션만 붙여주면 된다. 스프링의 트랜잭션 AOP는 이 애노테이션을 인식해서 트랜잭션 프록시를 적용해준다.
  • org.springframework.transaction.annotation.Transactional

예)

  • 서비스
@Slf4j
@RequiredArgsConstructor
public class MemberServiceV3_3 {

    private final MemberRepositoryV3 memberRepositoryV3;

    @Transactional
    public void accountTransfer(String fromId, String toId, int money) throws SQLException {
        // 비즈니스 로직
        Member fromMember = memberRepositoryV3.findById(fromId);
        Member toMember = memberRepositoryV3.findById(toId);

        memberRepositoryV3.update(fromId, fromMember.getMoney() - money);
        if(toMember.getMemberId().equals("ex")) {
            throw new IllegalStateException("이체중 예외 발생");
        }

        memberRepositoryV3.update(toId, toMember.getMoney() + money);
    }
}
  • TEST
    • @SpringBootTest
      • 스프링 AOP를 적용하려면 스프링 컨테이너가 필요하다
    • @TestConfiguration
      • 테스트 안에서 내부 설정 클래스를 만들어서 사용하면서 이 에노테이션을 붙이면, 스 프링 부트가 자동으로 만들어주는 빈들에 추가로 필요한 스프링 빈들을 등록하고 테스트를 수행할 수 있다.
    • TestConfig
      • DataSource
        • 스프링에서 기본으로 사용할 데이터소스를 스프링 빈으로 등록한다. 추가로 트랜잭션 매니 저에서도 사용한다.
      • DataSourceTransactionManager
        • 트랜잭션 매니저를 스프링 빈으로 등록한다. 스프링이 제공하는 트랜잭션 AOP는 스프링 빈에 등록된 트랜잭션 매니저를 찾아서 사용하기 때문에 트랜잭션 매니저를 스프링 빈으로 등록해두어야 한다.
    • 실제 실행 시 서비스의 클래스를 확인하면 프록시가 나온다
      • class hello.jdbc.service.MemberServiceV3_3$$SpringCGLIB$$0
@Slf4j
@SpringBootTest
class MemberServiceV3_3Test {

	...
	
    @Autowired
    private MemberRepositoryV3 memberRepository;
    @Autowired
    private MemberServiceV3_3 memberService;

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

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

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

        @Bean
        MemberServiceV3_3 memberServiceV33() {
            return new MemberServiceV3_3(memberRepositoryV3());
        }
    }
	
	...
}

흐름

profile
진짜 개발자가 되어보자

0개의 댓글