Home  >  Article  >  类库下载  >  spring transaction rollback

spring transaction rollback

高洛峰
高洛峰Original
2016-10-17 09:31:372029browse

1. Problems encountered

When we have multiple database save operations in one method, an error occurs in the middle database operation. The pseudo code is as follows:

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)。

spring transaction rollback

2) Error exception

  Error indicates that a very serious and unrecoverable error occurred during the running of the program. In this case, the application can only terminate the operation, such as an error in the JAVA virtual machine. . Error is an unchecked Exception. The compiler does not check whether the Error has been handled, and there is no need to catch Error type exceptions in the program. Under normal circumstances, exceptions of type Error should not be thrown in programs.

3) RuntimeException

 Exception includes RuntimeException and other non-RuntimeException exceptions.
 RuntimeException is an Unchecked Exception, which means that the compiler will not check whether the program handles RuntimeException. There is no need to catch RuntimException type exceptions in the program, and there is no need to declare the RuntimeException class in the method body. When a RuntimeException occurs, it means that a programming error has occurred in the program, so the error should be found and the program modified instead of catching the RuntimeException.

4) Checked Exception

Checked Exception, which is also the most used Exception in programming. All exceptions that inherit from Exception and are not RuntimeException are checked Exceptions, IOException and ClassNotFoundException in the above figure. The JAVA language stipulates that checked Exception must be processed. The compiler will check this and either declare a checked Exception in the method body or use a catch statement to capture the checked Exception for processing. Otherwise, it cannot be compiled.

3. Example

The transaction configuration used here is as follows:

<!-- 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" />

In the spring configuration file, if the defaultAutoCommit of the data source is set to True, then if the method catches an exception, the transaction will not be rolled back , if you don’t catch the exception yourself, the transaction will be rolled back, as in the following example
For example, if there is such a record in the configuration file

<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>

Maybe you will find that you have not configured this parameter, will it not automatically submit? The answer is no Yes, I use com.alibaba.druid.pool.DruidDataSource as the database connection pool. The default defaultAutoCommit is true. You can see the source code below

spring transaction rollback

 then there are two situations
 Case 1: If there is no Manually catching exceptions in the program

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

Situation 2: If the exception is caught in the program

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

Now what if we need to manually catch the exception and also want to be able to rollback when the exception is thrown?
 Just write the following to manually roll back the transaction:

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


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn