>  기사  >  类库下载  >  스프링 트랜잭션 롤백

스프링 트랜잭션 롤백

高洛峰
高洛峰원래의
2016-10-17 09:31:371987검색

1. 문제 발생

한 가지 방법으로 여러 개의 데이터베이스 저장 작업을 수행할 경우 중간 데이터베이스 작업에서 오류가 발생합니다. 의사 코드는 다음과 같습니다.

public method() {
    Dao1.save(Person1);
    Dao1.save(Person2);

    Dao1.save(Person2);//假如这句发生了错误,前面的两个对象会被保存到数据库中
    Dao1.save(Person2);
}
  期待的情况:发生错误之前的所有数据库保存操作都回滚,即不保存
  正常情况:前面的数据库操作会被执行,而发生数据库操作错误开始及之后的所有的数据保存操作都将失败。这样子应该都不是我们要的结果吧。
  当遇到这种情况,我们就可以使用Spring的事务解决这个问题。
2、异常的一些基本知识
1) 异常的架构
  异常的继承结构:Throwable为基类,Error和Exception继承Throwable,RuntimeException和IOException等继承Exception。Error和RuntimeException及其子类成为未检查异常(unchecked),其它异常成为已检查异常(checked)。

스프링 트랜잭션 롤백

2) 오류 예외

오류는 작업 중에 매우 심각하고 복구할 수 없는 오류가 발생했음을 나타냅니다. 프로그램 실행 중, 이 경우 애플리케이션은 실행을 중지할 수만 있습니다. 예를 들어 JAVA 가상 머신에 오류가 발생합니다. 오류는 확인되지 않은 예외입니다. 컴파일러는 오류가 처리되었는지 여부를 확인하지 않으며 프로그램에서 오류 유형 예외를 포착할 필요가 없습니다. 일반적인 상황에서는 프로그램에서 Error 유형의 예외가 발생해서는 안 됩니다.

3) RuntimeException

예외에는 RuntimeException 및 기타 RuntimeException이 아닌 예외가 포함됩니다.
RuntimeException은 확인되지 않은 예외입니다. 즉, 컴파일러는 프로그램이 RuntimeException을 처리하는지 여부를 확인하지 않습니다. 프로그램에서 RuntimException 유형의 예외를 포착할 필요가 없으며 RuntimeException 클래스를 선언할 필요도 없습니다. 메소드 본문. RuntimeException이 발생하면 프로그램에 프로그래밍 오류가 발생했다는 의미이므로 RuntimeException을 잡는 대신 오류를 찾아 프로그램을 수정해야 합니다.

4) Checked Exception

프로그래밍에서 가장 많이 사용되는 Exception이기도 한 Checked Exception은 RuntimeException이 아닌 Exception을 상속한 모든 예외를 말합니다. 위 그림의 IOException은 다음과 같습니다. 및 ClassNotFoundException. JAVA 언어는 확인된 예외가 처리되어야 한다고 규정합니다. 컴파일러는 이를 확인하고 메서드 본문에서 확인된 예외를 선언하거나 처리를 위해 확인된 예외를 캡처하기 위해 catch 문을 사용합니다.

3. 예시

여기에 사용된 트랜잭션 구성은 다음과 같습니다.

<!-- Jpa 事务配置 -->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>
    
    <!-- 开启注解事务 -->
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />

Spring 구성 파일에서 데이터 소스의 defaultAutoCommit이 True로 설정된 경우 , 그런 다음 메소드는 예외를 직접 catch하면 트랜잭션이 롤백되지 않습니다. 예외를 직접 catch하지 않으면 트랜잭션이 롤백됩니다. 예를 들어
과 같은 기록이 있습니다.

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> 

<property name="xxx" value="xxx"/> 

<property name="xxx" value="xxx"/>

 ....
 <property name="defaultAutoCommit" value="true" /> 

</bean>

구성 파일에서 이 매개변수를 구성하지 않은 것을 발견할 수 있습니다. 대답은 '아니오'입니다. 데이터베이스 연결 풀 기본 defaultAutoCommit은 true입니다. 아래 소스 코드를 살펴보세요.

스프링 트랜잭션 롤백

그렇다면 이제 두 가지 상황이 있습니다.
상황 1: 예외인 경우 프로그램에서 수동으로 catch되지 않습니다

@Transactional(rollbackOn = { Exception.class })  
public void test() throws Exception {  
     doDbStuff1();  
     doDbStuff2();//假如这个操作数据库的方法会抛出异常,现在方法doDbStuff1()对数据库的操作   会回滚。  }

상황 2: 프로그램에서 직접 예외를 catch하는 경우

@Transactional(rollbackOn = { Exception.class })  
public void test() {  
     try {  
        doDbStuff1();  
        doDbStuff2();//假如这个操作数据库的方法会抛出异常,现在方法doDbStuff1()对数据库的操作  不会回滚。  
     } catch (Exception e) {  
           e.printStackTrace();     
     }  
}

이제 예외를 수동으로 catch해야 하고 예외가 발생하면 롤백할 수 있나요?
트랜잭션을 수동으로 롤백하려면 다음과 같이 작성하세요.

@Transactional(rollbackOn = { Exception.class })  
public void test() {  
     try {  
        doDbStuff1();  
        doDbStuff2();  
     } catch (Exception e) {  
          e.printStackTrace();     
          TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//就是这一句了,加上之后,如果doDbStuff2()抛了异常,                                                                                       //doDbStuff1()是会回滚的  
     }  
}


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