>  기사  >  Java  >  Spring의 @Transactional 트랜잭션 롤백 예제 및 소스 코드에 대한 자세한 소개(그림)

Spring의 @Transactional 트랜잭션 롤백 예제 및 소스 코드에 대한 자세한 소개(그림)

黄舟
黄舟원래의
2017-03-30 11:00:592105검색

1. 사용 시나리오 예시

@Transactional의 사용법을 이해하기 전에 먼저 @Transactional의 용도를 알아야 합니다. 예를 들면 다음과 같습니다. 예를 들어 부서 테이블과 멤버 테이블에 각각 많은 구성원이 저장되어 있다고 가정합니다. 부서를 삭제할 때 기본적으로 해당 구성원을 삭제한다고 가정합니다. 그런데 실행 중에 이런 상황이 발생할 수 있습니다. 부서를 먼저 삭제한 후 구성원을 삭제합니다. 그러나 부서는 성공적으로 삭제되지만 구성원을 삭제하는 경우 예외가 발생합니다. 이때, 회원 삭제에 실패할 경우 이전에 삭제된 부서도 삭제 취소가 되기를 바랍니다. 이 시나리오에서는 @Transactional 트랜잭션 롤백을 사용할 수 있습니다.

2. Checked 예외와 Unchecked 예외

Checked 예외와 Unchecked 예외의 개념을 모두가 명확히 알고 있는 이유는

Spring이 선언적 트랜잭션을 사용하기 때문입니다. 처리 중, 기본적으로 주석이 달린 데이터베이스 작업 메서드에서 확인되지 않은 예외가 발생하면 모든 데이터베이스 작업이 롤백됩니다. 발생한 예외가 확인된 예외인 경우 데이터베이스 작업은 기본적으로 계속 제출됩니다.

확인된 예외:

는 유효하지 않으며 프로그램에서 예측할 수 없음을 의미합니다. 예를 들어 잘못된 사용자 입력, 파일이 존재하지 않음, 네트워크 또는 데이터베이스 링크 오류 등이 있습니다. 이는 모두 외부적인 이유이며 프로그램 내에서 제어할 수 없습니다.

은 코드에서 명시적으로 처리되어야 합니다. 예를 들어 블록 처리를 시도하거나 메서드에 throws 설명을 추가하여 호출 스택의 상위 계층에 예외를 발생시킵니다.

java.lang.Exception에서 을 상속합니다(java.lang.RuntimeException 제외).

확인되지 않은 예외:

는 오류, 즉 프로그램의 논리적 오류를 나타냅니다. IllegalArgumentException, NullPointerException 및 IllegalStateException과 같은 RuntimeException의 하위 클래스입니다.

처리를 위해 코드에서 확인되지 않은 예외를 명시적으로 포착할 필요가 없습니다.

java.lang.RuntimeException에서 상속됩니다(그리고 java.lang.RuntimeException은 java.lang.Exception에서 상속됩니다).

더 깊은 계층 구조를 가질 수 있는 아래 예외 구조 다이어그램을 살펴보세요.

Spring의 @Transactional 트랜잭션 롤백 예제 및 소스 코드에 대한 자세한 소개(그림)

3. @Transactional의 사용 예

이 예제는 Eclipse+maven을 사용합니다. Maven을 이해하지 못하는 사람이라도 이해할 수 있습니다.

3.1. Spring의 구성 파일

은 먼저 tx 네임스페이스를 다음과 같이 구성해야 합니다.

Spring의 @Transactional 트랜잭션 롤백 예제 및 소스 코드에 대한 자세한 소개(그림)

@Transactional 기반 트랜잭션 관리를 사용하려면 Spring에서 다음 구성을 수행해야 합니다.

<bean id="appTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property name="dataSource" ref="dataSource" />
    </bean>

    <tx:annotation-driven proxy-target-class="false" transaction-manager="appTransactionManager" />

블로거의 전체 Spring 구성 파일:




       
     
        
            
               classpath:properties/*.properties
                
            
        
    

    
    
        
        
       
        
            ${jdbc_driverClassName}
        
        
            ${jdbc_url}
        
        
            ${jdbc_username}
        
        
            ${jdbc_password}
        
    

    <bean id="appTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property name="dataSource" ref="dataSource" />
    </bean>

    <tx:annotation-driven proxy-target-class="false" transaction-manager="appTransactionManager" />

    
    
        
    

    
    
        
          
        
        
    

    
    

3.2. @Transactional을 사용하고 에 user 구현 클래스 메서드를 추가하고

@Transactional(propagation=Propagation.REQUIRED)
public void addUser(User user) {
    userDao.addUser(user);
    String string  = null;
    if(string.equals("")) {
        int i = 0;
    }
}

주석을 추가합니다. 위 메서드에서 의도적으로 null 포인터 예외가 발생하여 모든 것이 롤백됩니다.

3.3. 유닛 테스트 클래스

@Test  
public void addUserTest(){  
    User user = new User();
    user.setUserName("luoguohui1");
    user.setUserPassword("luoguohui1");
    userService.addUser(user);
}

를 실행하여 삽입할 수 없는 것을 확인하지만 @Transactional이 제거되면 코드 다음과 같습니다. 예외가 발생했지만 여전히 데이터베이스에 뭔가가 있습니다. 해당 데이터 추가:

Spring의 @Transactional 트랜잭션 롤백 예제 및 소스 코드에 대한 자세한 소개(그림)

3.4, 소스 코드 다운로드

이 글의 프로젝트는 mybatis 입문용입니다(예제 튜토리얼 및 소스 코드 포함). 를 기반으로 수정되었으며, 이 글에는 데이터베이스 스크립트 및 프로젝트 구성의 세부 프로세스가 포함되어 있습니다.

4. Spring의 @Transactional에 대해 이해해야 할 개념

Spring의 @Transactional은 동적 프록시 메커니즘을 기반으로 하며, 이는 투명하고 편리한 트랜잭션 관리 메커니즘을 제공합니다. 개발 중에 발생한 문제를 해결합니다.

일반적인 용도는 다음 코드를 통해 메서드, 인터페이스 또는 클래스 에 주석을 달는 것입니다.

@Transactional(propagation=Propagation.NOT_SUPPORTED)

전파는 7가지 다른 전파 메커니즘을 지원합니다.

필수 : 트랜잭션이 존재하는 경우 현재 트랜잭션이 지원됩니다. 거래가 없으면 새 거래를 시작하십시오.

지원: 거래가 존재하는 경우 현재 거래를 지원합니다. 트랜잭션이 없으면 트랜잭션이 실행되지 않습니다. 그러나 트랜잭션 동기화를 사용하는 트랜잭션 관리자의 경우 PROPAGATION_SUPPORTS는 트랜잭션을 사용하지 않는 것과 약간 다릅니다.

NOT_SUPPORTED: 항상 비트랜잭션으로 실행하고 기존 트랜잭션을 일시 중지합니다.

필수사항신규: 항상 새 거래를 시작하세요. 거래가 이미 존재하는 경우 기존 거래가 일시 중지됩니다.

필수: 거래가 이미 존재하는 경우 현재 거래가 지원됩니다. 활성 트랜잭션이 없으면 예외가 발생합니다.

NEVER: 항상 비트랜잭션으로 실행합니다. 활성 트랜잭션이 있으면 예외를 발생시킵니다.

NESTED: 활성 트랜잭션이 있으면 중첩 트랜잭션에서 실행합니다. 활성 트랜잭션이 없으면 REQUIRED속성에 따라 실행합니다.

다음은 주의해야 할 사항입니다. 그렇지 않으면 다양한 함정에 직면하게 됩니다. 블로거가 상기시키지 못했다고 말하지 마세요 :

주의해야 할 사항은 다음과 같습니다. 그렇지 않으면 다양한 함정에 직면했을 때 블로거가 알려주지 않았다고 말하지 마세요. >

다음은 주의해야 할 사항입니다. 반드시 읽어야 합니다. 그렇지 않으면 다양한 함정에 직면했을 때 블로거가 알림을 주지 않았다고 말하지 마세요.

:

    트랜잭션 관리가 필요한 곳에 @Transactional 주석을 추가합니다. @Transactional 주석은 인터페이스 정의와 인터페이스 메서드, 클래스 정의 및 클래스의 공용 메서드에 적용될 수 있습니다.
  • @Transactional 주석은 공개 가시성이 있는 메소드에만 적용될 수 있습니다. 보호된 프라이빗 또는 패키지 표시 메서드에서 @Transactional 주석을 사용하는 경우 오류를 보고하지 않지만 주석이 달린 메서드는 구성된 트랜잭션 설정을 표시하지 않습니다.
  • 단순히 @Transactional 주석이 나타나는 것만으로는 트랜잭션
  • 행동

    을 가능하게 하는 데 충분하지 않으며 일종의 메타데이터일 뿐입니다. 실제로 트랜잭션 동작을 활성화하려면 구성 파일에서 구성 요소를 사용해야 합니다.

  • 요소의 "proxy-target-class" 속성 값을 사용하여 인터페이스 기반 또는 클래스 기반 프록시 생성 여부를 제어합니다. "proxy-target-class" 속성 값이 "true"로 설정되면 클래스 기반 프록시가 작동합니다(이를 위해서는 CGLIB 라이브러리 cglib.jar이 CLASSPATH에 있어야 함). "proxy-target-class" 속성 값이 "false"로 설정되거나 이 속성이 생략되면 표준 JDK 인터페이스 기반 프록시가 사용됩니다.
  • Spring 팀은 클래스가 구현하려는 인터페이스보다는 특정 클래스(또는 클래스 메서드)에 @Transactional 주석을 사용할 것을 권장합니다. 인터페이스에서 @Transactional 주석을 사용하면 인터페이스 기반 프록시를 설정한 경우에만 적용됩니다. 주석은 상속 가능하지 않기 때문에 클래스 기반 프록시를 사용하는 경우 트랜잭션 설정이 클래스 기반 프록시에서 인식되지 않으며
  • 개체

    가 트랜잭션 프록시에서 인식되지 않습니다. . 패키지.

  • @Transactional 트랜잭션이 열리거나 인터페이스 기반 또는 클래스 기반 프록시가 생성됩니다. 따라서 동일한 클래스의 메서드가 트랜잭션이 있는 다른 메서드를 호출하면 트랜잭션이 작동하지 않습니다.

위 내용은 Spring의 @Transactional 트랜잭션 롤백 예제 및 소스 코드에 대한 자세한 소개(그림)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.