상세 컨텐츠

본문 제목

선언적 Transactional

Spring Data

by Wanderer Kim 2021. 9. 19. 19:40

본문

728x90
  • 스트링에서 트랜잭션 처리 방법
    • 스트링에서는 트랜잭션 처리를 @Transactional을 사용하는 방법을 제공한다. 이를 선언적 트랜잭션이라 부른다.
    • 스프링에서는 @Transactional을 사용하면 해당 어노테이션이 명시된 모든 메소드들에 대해 내부적으로 AOP를 사용하여 트랜잭션 처리 코드가 전/후로 수행된다.
  • Spring에서 Transaction 관리를 위해 사용되는 AOP 프록시 매커니즘
    • JDK Dynamic Proxy
      • 인터페이스에 대한 proxy만을 지원하며, 클래스에 대한 proxy를 지원할 수 없다.
    • CGLIB Proxy
      • Runtime시에 target 메소드가 호출될 때 해당 메소드의 advice 적용 여부를 결정한다. 그러나 메소드는 처음 호출 되었을때 동적으로 bytecode를 생성하여 이후 호출에서는 재사용하는 과정을 거치게 된다. 그리하여 두번째 호출이후부터는 싱행속도의 향상을 가져올 수 있다.
      • CGLIB Proxy는 클래스에 대한 proxy가 가능하다.
  • Spring Boot에서의 설정 및 Transaction 속성
    • Spring Boot에서는 어노테이션 사용이 바로 사용 가능하다. (CGLIB Proxy Default)
    • 트랜잭셩의 속성1 (전파 - propation)
      • 트랜잭션의 경게를 정의하며 시작 방법을 셜정하는 속성이다.
        전파 속성 설명
        REQUIRED (Default) 트랜잭션의 시작 시점에 이미 진행중인 트랜잭션이 잇으면 해당 트랜잭션에 참여하며 없을 경우 새로운 트랜잭션을 시작한다.
        REQUIRES_NEW 항상 새로운 트랜잭션을 시작한다. 이미 진행중인 트랜잭션이 있다면 잠깐 보류되고 해당 트랜잭션 경계가 종료 된 후 다시 시작횐다.
        SUPPORT 이미 진행중인 트랜잭션이 있으면 참여하고, 없을 경우 Non-transaction으로 시작한다.
        MANDATORY 이미 진행중인 트랜잭션이 반드시 있어야만 해당 경계를 넘어 시작할 수 있다. 없을 경우 Exception을 발생 시킨다.
        NOT_SUPPORT Non-transaction으로 시작하며, 이미 진행중인 트랜잭션이 있으면 잠시 보류 시킨다.
        NEVER Non-transaction 상테에서만 새당 경계를 넘어갈 수 있다. 이미 진행중인 트랜잭션이 있으면 예외를 발생 시킨다.
        NESTED 이미 진행중인 트랜잭션이 있을 경우 중첨 트랜잭션을 생성하여 시작한다. 생성된 중첨 트랜잭션언 (parent)가 rollback되면 함께 되지만, 해당 트랜잭션안에서의 commit/rollback은 (parent)에 영항을 주지 않는다.
        이미 진행중인 트랜잭션이 없을 경우 새로운 트랜잭션을 만든다.
    • 트랜잭션의 속성2 (격리수준-isolation)
      • 동시에 여러 thread 별로 여러 트랜잭션이 진행될 때, 결과를 타 트랜잭션에 어떻게 노출할 것인지를 결정한다.
        격리 수준 설명
        DEFAULT 사용하는 데이터 엑세스 기술 또는 DB 드라이버의 기본 설정을 따른다. 대부분 DB는 READ_COMMITTED를 기본으로 한다.
        READ_UNCOMMITTED 가장 낮은 격리수준이다. 트랜잭션의 종료에 따른 commit/rollback이 이루어지지 않아도 해당 변화가 ㅏ다른 트랜잭션에 노출된다. (성능은 가장 좋다)
        READ_COMMITTED commit/rollback이 이루어지지 않은 정보는 다른 트랜잭션에서 읽을 수 없다. 서로 다른 트랜잭션이 동시에 row를 핸들링하는 경우 의도치 않은 결과가 올 수 있다.
        REPEATABLE_READ 하나의 트랜잭션이 읽은 row를 다른 트랜잭션이 수정하는 것을 막아준다 하짐나 새로운 row 추가는 제한 않는다.
        SELECT 후 타 트랜잭션에서 추가로 결과가 달라질 수 있다.
        SERIALIZABLE 가장 강력한 격리 수준이다. 순차적으로 진행해서 여러 트랜잭션이 동시에 같은 테이블 정보를 엑세스하지 못하게 한다. (성능은 가장 낮다)
    • 트랜잭션의 속성3 (Rollback, Commit 관련)
      • 선언적 트랜잭션에서는 트랜잭션 경계지점(Method)를 기전으로 다시 제어가 돌아 왔을때(해당 method가 끝날때), 아무 exception 발생없이 끝나면 commit, RuntimeException이 throw 되면 rollback 한다. Exception(checked)의 경우 commit이 DEFAULT 이다.
        속성 설명
        rollbackFor (rollback 조건-Exception 변경) rollback이 이루어지는 Exception을 변경한다.
        noRollbackFor (commit 조건-Exception 변경) commit이 이루어지는 Exception을 추가한다.
    • 트랜잭션의 속성4 (읽기 전용 - readOnly)
      • 트랜잭션을 읽기 전용으로 설정한다. 성능 최적화 혹은 의도적으로 조회만을 위한 트랜잭션을 만들기 위해 사용할 수 있다.
  • Spring Boot 에서 트랜잭션 설정 방법
    • Spring Boot 프로젝트에서 spring-data- dependency들이 classpath에 추가되어 있다면 transaction management가 자동으로 활성화되어 있다.
    • 만약 자동 설정이 아닌 java config 방식으로 사용하고 싶다면 datasource configuration 클래스에 @EnableTransactionManagement를 추가하는 방식으로 사용할 수 있다.
  • 선언적 트랜잭션 사용
    • 경계로 가져가고 싶은 클래스, 인터페이스, 메소드에 아래과 같이 지정하여 사용할 수 있다.
    • @Transactional 
      public void batchEvent(){ 
      	try{ 
          	apiCallAndAddEvents(); 
              apiCallAndAddSubjcode(); 
              commService.addBatchJobLog("OK"); 
          } catch(Exception e){ 
          	commService.addBatchJobLog("FAIL"); 
              throw new RuntimeException(e); 
          } 
      }
    • @Transactional 은 클래스 또는 메소드위에 사용 가능하면 이때, 적용되는 클래스 또는 메소드는 public 이어야한다.
    • 어노테이션이 중복으로 적용될 경우 메소드 < 클래스 < 인터페이스 순으로 우선순위가 정해진다.
    • 위 코드르 설명하자면 apiCallAndAddEvents(), apiCallAndAddSubjcode() 가 트랜잭션으로 묶여 처리되고 정상적으로 종료되면 로그 (OK)를 적재하며, Exception이 발생할 경우 오류 로그 (FAIL)을 남기는 로직이다.
반응형

'Spring Data' 카테고리의 다른 글

트랜잭션 이해  (0) 2025.01.05
DataSource 이해  (0) 2024.11.30
커넥션 풀  (0) 2024.11.17
Spring Transaction 사용 시 주의할 점  (0) 2021.09.25

관련글 더보기

댓글 영역