SEB_BE 53일차 - 트랜잭션2

subimm_·2022년 11월 7일

코드스테이츠

목록 보기
53/83

💡 오늘의 학습목표

  • 선언형 방식의 트랜잭션
  • JTA를 이용한 분산 트랜잭션

📔 Spring Framework에서의 트랜잭션 처리

  • 로컬 트랜잭션 / 분산 트랜잭션
  • Spring에서 사용되는 트랜잭션 방식은 선언형 / 프로그래밍 코드 베이스 방식
    • 트랜잭션은 부가 기능 AOP의 적용 대상 중 하나

📖 선언형 방식의 트랜잭션 적용

  • 애너테이션 방식의 트랜잭션 적용
    ✔ 클래스 레벨에 @Transactional 적용


    ✔ rollback 동작 유무 확인
  • 회원 정보를 저장하고 메서드가 종료되기 전에 강제로 런타임예외 발생시키기

    체크 예외는 rollback이 잘 될까?
    캐치 한 후에 해당 예외를 복구할지 회피할지 등의 예외 전략 고민해야함.
    예외 전략을 짤 필요 없다면 @Transactional(rollbackFor={SQLException.class, DataFormatException.class}) 와 같이 직접 지정해주거나 언체크 예외로 감싸서 rollback이 동작하도록 할 수 있다.

✔ 메서드 레벨에 @Transactional 적용

  • 읽기 전용 트랜잭션이 적용됨.
    • 조회 메서드에 @Transactional(readOnly = true) 로 설정하는 이유
      findMember() 와 같은 조회 메서드에 읽기전용으로 설정해도 commit 절차를 진행하긴한다.
      읽기 전용으로 설정하면 JPA 내부적으로 영속성 컨텍스트를 flush 하지 않음.
      변경 감지를 위한 스냅샷 생성도 진행하지 않는다.
      (성능 최적화)

✔ 클래스 레벨과 메서드 레벨의 트랜잭션 적용 순서

  • 클래스 레벨에만 @Transactional이 적용된 경우
    • 클래스 레벨의 @Transactional 애너테이션이 메서드에 일괄 적용
  • 클래스 레벨과 메서드 레벨에 함께 적용된 경우
    • 메서드 레벨의 @Transactional 애너테이션이 적용됨.
    • 메서드 레벨에 애너테이션이 적용되지 않았을 경우, 클래스 레벨의 @Transactional 애너테이션이 적용된다.

📖 여러 작업이 하나의 트랜잭션으로 묶이는 경우

  • 트랜잭션이 하나로 묶여있기 때문에 MemberService의 updateStamp() 메서드 작업을 처리하는 도중에 예외가 발생해도 두 클래스에서 작업을 처리하는 메서드들이 모두 하나의 트랜잭션 내에 있으므로 모두 rollback
  • MemberService
  • (1) 과 같이 propagation 애트리뷰트의 값으로 Propagation.REQUIRED 를 지정하면 메서드 실행 시, 현재 진행 중인 트랜잭션이 존재하면 해당 트랜잭션을 사용하고, 존재하지 않으면 새 트랜잭션을 생성하도록 해준다.
  • 따라서 OrderService에서 createOrder() 메서드를 호출하면 트랜잭션이 하나 생성, createOrder()메서드 내에서 updateMember() 메서드를 호출하면 현재 OrderService에서 진행중인 트랜잭션에 참여
  • 실행 결과 rollback 진행됨. 주문 정보, 스탬프 정보 둘다 반영x
  • 트랜잭션 전파 (Transaction Propagation)
    • 트랜잭션의 경계에서 진행 중인 트랜잭션이 존재할 때 또는 존재하지 않을 때, 어떻게 동작할 것인지 결정하는 방식
    1. Propagation.REQUIRED (디폴트)
      진행중인 트랜잭션이 없으면 새로 시작하고, 진행 중인 트랜잭션이 있으면 해당 트랜잭션에 참여
    2. Propagation.REQUIRES_NEW
      이미 진행중인 트랜잭션과 무관하게 새로운 트랜잭션 시작, 기존 진행중은 새로 시작된 트랜잭션이 종료할 때까지 중지됨.
    3. Propagation.MANDATORY
      진행중인 트랜잭션이 없으면 예외를 발생시킴.
    4. Propagation.*NEVER*
      트랜잭션을 필요로 하지 않음, 진행 중인 트랜잭션이 존재할 경우에는 예외 발생
  • 트랜잭션 격리 레벨 (Isolation Level)
    • 결리성을 조정할 수 있는 옵션
    1. Isolation.DEFAULT
      데이터베이스에서 제공하는 기본 값
    2. Isolation.READ_UNCOMMITTED
      다른 트랜잭션에서 커밋하지 않은 데이터를 읽는 것을 허용
    3. Isolation.READ_COMMITTED
      다른 트랜잭션에 의해 커밋된 데이터를 읽는 것을 허용
    4. Isolation.REPEATABLE_READ
      트랜잭션 내에서 한 번 조회한 데이터를 반복해서 조회해도 같은 데이터가 조회되게 함.
    5. Isolation.SERIALIZABLE
      동일한 데이터에 대해서 동시에 두 개 이상의 트랜잭션이 수행되지 못하도록 함.

📖 AOP 방식의 트랜잭션 적용

  • CoffeeService에 적용
  1. AOP방식으로 트랜잭션을 적용하기 위한 Configuration 클래스 정의
    (1)과 같이 애너테이션을 추가하여 Configuration 클래스 정의
  2. TransactionManager DI
    애플맄이션에 트랜잭션을 적용하기 위해서는 TransactionManager 객체가 필요
    (2) 와 같이 객체를 DI 받기
  3. 트랜잭션 어드바이스용 TransactionInterceptor 빈 등록
    Spring에서는 TransactionInterceptor를 이용해서 대상 클래스 또는 인터페이스에 트랜잭션 경계를 설정하고 적용
  • 트랜잭션 애트리뷰트 지정
    메서드 이름 패턴에 따라 구분해서 적용 가능하기 때문에 (3), (4) 와 같이 설정 가능
    (3)은 조회 메서드를 제외한 공통 트랜잭션 애트리뷰트
    (4)는 조회 메서드에 적용하기 위한 애트리뷰트
  • 트랜잭션을 적용할 메서드에 트랜잭션 애트리뷰트 매핑
    (5)와 같이 Map에 추가하여 key를 메서드 이름 패턴 으로 지정해서 각각의 트랜잭션 애트리뷰트를 추가
    (6) 추가한 Map 객체를 넘겨줌
  • TransactionIntercepter 객체 생성
    (7) 생성자 파라미터로 전달
  1. Advisor 빈 등록
  • 포인트 컷 지정
    (8) 과 같이 AspectJExpressionPointcut 객체 생성 후 , 포인트 컷 표현식으로 CoffeeService 클래스를 타겟 클래스로 지정
  • Advisor 객체 생성
    (9)와 같이 생성자 파라미터로 포인트컷과 어드바이스를 전달

트랜잭션 적용 실습

회원 등록과 이메일 전송에 대한 트랜잭션 처리

  • Async 로 비동기 처리 / 이벤트 처리


참고 : https://shinsunyoung.tistory.com/88

📙 [심화] JTA를 이용한 분산 트랜잭션 적용

  • 서로 다른 데이터소스를 사용하는 한 개 이상의 데이터베이스를 하나의 트랜잭션으로 묶어서 처리해야하는 경우
    ( 추가 예정 )
profile
코린이의 공부 일지

0개의 댓글