
트랜잭션 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());
}
}
...
}
흐름
