Transaction

귀찮Lee·2022년 7월 13일
0

Spring

목록 보기
24/30
post-thumbnail

◎ Transaction

  • Transaction : DB에서 데이터에 대한 하나의 논리적 실행단계

    • DB에서만 한정적으로 사용하는 것이 아닌, 하나의 작업단위로 묶어서 작업하는 중 All or Nothing이 필요할 때, 트랙젝션으로 묶어서 실행할 수 있다.
  • ACID 원칙을 지킴
    (원자성-Atomicity, 일관성-Consistency, 격리성-Isolation, 지속성-Durability)

  • 커밋과 롤백

    • 커밋(Commit)

      • 최종적으로 DB에 반영하는 명령어, 변경된 내용을 영구적으로 저장
      • commit을 하지 않으면, DB에 반영되지 않음
      • commit이 되면, 하나의 트랜젝션을 종료
    • 롤백(Rollback)

      • 작업중에 문제 발생시, 트랜젝션 내의 수행된 작업들을 전부 취소
      • 트랜젝션 이전의 상태로 돌아감

◎ Transaction의 과정

  • 복잡한 과정을 거쳐서 commit이 수행됨

◎ Transaction 적용

  • 클래스 레벨에서 @Transaction 적용

    • 그 클래스에 있는 모든 메서드에서 트렌젝션이 적용됨
    • 내부 메서드마다 특정 설정을 해주고 싶다면, 메서드 레벨에서 @Transaction 을 사용
    @Service
    @Transactional
    public class MemberService {
        ...
    }
  • 메서드 레벨에서 @Transaction 적용

    • 특정 메서드에서만 @Transaction 적용 가능

    • 클래스 레벨에서 Transaction에서 일부 설정 해야할것이 있다면, 메서드에 붙여 사용해서 적용가능 (메서드 레벨에 있는 설정 우선 참고)

      @Service
      @Transactional  
      public class MemberService {
          ...
      
          @Transactional(readOnly = true)
          public Member findMember(long memberId) {
              return findVerifiedMember(memberId);
          }
      
      }
    • AOP 방식의 트랜젝션 적용

      @Configuration
      @RequiredArgsConstructor // 생성자 주입
      public class TxConfig {
         private final TransactionManager transactionManager;
      
         @Bean
         public TransactionInterceptor txAdvice() {
             NameMatchTransactionAttributeSource txAttributeSource =
                                         new NameMatchTransactionAttributeSource();
      
      		// 공통 트랜잭션 애트리뷰트
             RuleBasedTransactionAttribute txAttribute =
                                             new RuleBasedTransactionAttribute();
             txAttribute.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
      
      		// 조회 메서드에 적용하기 위한 트랜잭션 애트리뷰트 ()
             RuleBasedTransactionAttribute txFindAttribute =
                                             new RuleBasedTransactionAttribute();
             txFindAttribute.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
             txFindAttribute.setReadOnly(true); // transaction 설정
      
      		// 트랜잭션을 적용할 메서드에 트랜잭션 애트리뷰트 매핑
             Map<String, TransactionAttribute> txMethods = new HashMap<>();
             txMethods.put("find*", txFindAttribute);
             txMethods.put("*", txAttribute);
      
      		// TransactionInterceptor 객체로 만들어 넘겨줌
             txAttributeSource.setNameMap(txMethods);
             return new TransactionInterceptor(transactionManager, txAttributeSource);
         }
      
         @Bean
         public Advisor txAdvisor() {
      		// pointcut을 이용하 타겟 클래스 지정
             AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
             pointcut.setExpression("execution(* com.codestates.coffee.service." +
                     "CoffeeService.*(..))");
      		
             // 이후 인자를 넘김
             return new DefaultPointcutAdvisor(pointcut, txAdvice());
         }
      }

◎ Transaction 특징 및 설정

  • 체크 예외(checked exeption) Rollback 안됨

    • 언체크 예외와 달리, 체크 예외는 어노테이션만 붙인다고 해서 Rollback하지 않는다.
      • 언체크 예외 : RuntimeException을 상속하는 예외
      • 체크 예외 : RuntimeException을 상속하지 않는 예외
    • try, catch를 이용하여 해당 예외를 복구할지 회피할지의 적당한 예외 전략을 고민해야 한다.
    • 별도의 전략이 필요없다면, 해당 예외를 지정해주거나 언체크 예외로 감싸서 rollback을 해줄 수 있다.
    @Transactional(rollbackFor = {SQLException.class, DataFormatException.class})
  • Transaction 설정

    • readOnly = true (default false)

      • HttpMethod 중에서 GET을 이용한 것(단순 조회만 하는 역할들)에서 사용하는 설정
      • JPA에서 commit이 호출될 시에는 내부적으로 영속성 컨텍스트가flush를 하는데, 위와 같은 설정을 할 경우에는 flush를 하지 않고, 변경 감지를 위한 snapshot도 남기지 않는다.
      • readOnly = true 를 통해 조회를 담당하는 메서드에서는 필요없는 과정을 하지 않아, 성능 최적화를 함
    • propagation

      • Propagation.REQUIRED (default): 트랜잭션이 없으면 새로 시작하고, 진행 중인 트랜잭션이 있으면 해당 트랜잭션에 참여 (위의 사진에 해당)
      • Propagation.REQUIRES_NEW : 무조건 새로운 트랜잭션이 시작, 기존 것은 중지함
      • Propagation.NOT_SUPPORTED : 트렌젝션이 필요하지 않음 (기존 것을 중단함)
      • Propagation.MANDATORY : 진행중인 트렌젝션이 없으면 예외 발생
      • Propagation.NEVER : 트렌젝션이 필요하지 않음, 진행중인 트렌젝션 존재시, 예외 발생
    • isolation (참고, 왠만하면 default 값을 사용)

profile
배운 것은 기록하자! / 오류 지적은 언제나 환영!

0개의 댓글