[66해빗 페이백 챌린지] 25일차

tree·2023년 5월 27일
0

트랜잭션 문제 해결 - 트랜잭션 템플릿

  • 트랜잭션 매니저를 사용하면 서비스 계층이 특정 DB 접근 기술의 트랜잭션 처리 코드에 의존하지 않아도 되고 커넥션 동기화를 쉽게 이용할 수 있다.
  • 트랜잭션 매니저의 한계
    • 트랜잭션 매니저를 사용하더라도 트랜잭션을 시작하고, 비즈니스 로직을 수행하고, 성공하면 커밋하고, 실패하면 롤백하는 코드가 반복되는 문제가 있다.
    • 바뀌는 건 비즈니스 로직 뿐인데 트랜잭션 처리 코드를 반복적으로 작성하는 건 피곤한 일이다.
  • 템플릿 콜백 패턴
    • 템플릿 콜백 패턴을 활용하면 반복되는 코드를 공통으로 처리하고 비즈니스 로직만 변경하여 코드를 작성할 수 있다.
    • 스프링에서 TrasactionTemplate이라는 트랜잭션 공통 처리를 위한 템플릿 클래스를 제공하여 비즈니스 로직만 작성하면 되도록 해준다.
  • TransactionTemplate의 한계
    • TransactionTemplate을 활용해도 서비스 계층에 비즈니스 로직과 트랜잭션 처리 코드가 같이 존재하게 된다.
      • 2가지 코드가 같이 존재하면 유지보수가 힘들어진다.

트랜잭션 문제 해결 - 트랜잭션 AOP 이해

  • 스프링 트랜잭션 AOP를 사용해 프록시를 도입하면 서비스 계층에 순수 비즈니스 로직만 남기는 것이 가능한다.
  • @Transactional을 사용하면 스프링 트랜잭션 AOP가 프록시를 자동으로 적용해준다.
    • org.springframework.transaction.annotation.Transactional

  • 프록시를 도입하면 트랜잭션 처리 로직을 프록시가 모두 가져간다. 그리고 실제 비즈니스 로직을 프록시가 호출하는 방식으로 동작한다.
public class TransactionProxy {

  private MemberService target;

  public void logic() {
    //트랜잭션 시작
    TransactionStatus status = transactionManager.getTransaction(..);

    try {
      target.logic(); //실제 대상 호출
      transactionManager.commit(status); //성공시 커밋
    } catch (Exception e) {
      transactionManager.rollback(status); //실패시 롤백
      throw new IllegalStateException(e);
    }
  }
}

public class Service {

  public void logic() {
    //트랜잭션 관련 코드 제거, 순수 비즈니스 로직만 남음
    bizLogic(fromId, toId, money);
  }
}
  • 스프링 부트를 사용하면 트랜잭션 AOP 처리를 위해 필요한 다음의 클래스들을 스프링 컨테이너에 자동으로 등록한다.
    • 어드바이저: BeanFactoryTransactionAttributeSourceAdvisor
    • 포인트컷: TransactionAttributeSourcePointcut
    • 어드바이스: TransactionInterceptor

0개의 댓글