Java  Spring 事务回滚详解


Posted in Javascript onOctober 17, 2016

spring 事务回滚

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

Java  Spring 事务回滚详解

2)Error异常

Error表示程序在运行期间出现了十分严重、不可恢复的错误,在这种情况下应用程序只能中止运行,例如JAVA 虚拟机出现错误。Error是一种unchecked Exception,编译器不会检查Error是否被处理,在程序中不用捕获Error类型的异常。一般情况下,在程序中也不应该抛出Error类型的异常。

3)RuntimeException异常

Exception异常包括RuntimeException异常和其他非RuntimeException的异常。

RuntimeException 是一种Unchecked Exception,即表示编译器不会检查程序是否对RuntimeException作了处理,在程序中不必捕获RuntimException类型的异常,也不必在方法体声明抛出 RuntimeException类。RuntimeException发生的时候,表示程序中出现了编程错误,所以应该找出错误修改程序,而不是去捕获RuntimeException。

4)Checked Exception异常

Checked Exception异常,这也是在编程中使用最多的Exception,所有继承自Exception并且不是RuntimeException的异常都是checked Exception,上图中的IOException和ClassNotFoundException。JAVA 语言规定必须对checked Exception作处理,编译器会对此作检查,要么在方法体中声明抛出checked Exception,要么使用catch语句捕获checked Exception进行处理,不然不能通过编译。

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了,那么方法中如果自己捕获了异常,事务是不会回滚的,如果没有自己捕获异常则事务会回滚,如下例
比如配置文件里有这么条记录

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

可能你会发现你并没有配置这个参数,是不是他就不会自动提交呢?答案是不是的,我这里是使用了com.alibaba.druid.pool.DruidDataSource作为数据库连接池,默认的defaultAutoCommit就是true,可以看下面的源码

 Java  Spring 事务回滚详解

那么现在有两个情况

情况1:如果没有在程序中手动捕获异常

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

情况2:如果在程序中自己捕获了异常

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

现在如果我们需要手动捕获异常,并且也希望抛异常的时候能回滚肿么办呢?

下面这样写就好了,手动回滚事务:

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

   感谢您的阅读!谢谢!

Javascript 相关文章推荐
jquery+json实现的搜索加分页效果
Mar 31 Javascript
用JavaScript仿PS里的羽化效果代码
Dec 20 Javascript
web开发人员学习jQuery的6大理由及jQuery的优势介绍
Jan 03 Javascript
jquery遍历select元素(实例讲解)
Dec 31 Javascript
JavaScript中指定函数名称的相关方法
Jun 04 Javascript
easyui datagrid 大数据加载效率慢,优化解决方法(推荐)
Nov 09 Javascript
JavaScript原生编写《飞机大战坦克》游戏完整实例
Jan 04 Javascript
vue-awesome-swiper滑块插件使用方法详解
Nov 27 Javascript
几个你不知道的技巧助你写出更优雅的vue.js代码
Jun 11 Javascript
微信小程序实现同一页面取值的方法分析
Apr 30 Javascript
vue组件化中slot的基本使用方法
May 01 Javascript
详解vue中使用protobuf踩坑记
May 07 Javascript
使用jquery.qrcode.js生成二维码插件
Oct 17 #Javascript
js浏览器html5表单验证
Oct 17 #Javascript
使用开源工具制作网页验证码的方法
Oct 17 #Javascript
jQuery 实现ajax传入参数含有特殊字符的方法总结
Oct 17 #Javascript
JavaScript中的ajax功能的概念和示例详解
Oct 17 #Javascript
JQuery中解决重复动画的方法
Oct 17 #Javascript
bootstrap读书笔记之CSS组件(上)
Oct 17 #Javascript
You might like
乱谈我对耳机、音箱的感受
2021/03/02 无线电
PHP 已经成熟
2006/12/04 PHP
PHP中判断变量为空的几种方法小结
2013/11/12 PHP
根据key删除数组中指定的元素实现方法
2017/03/02 PHP
PHP使用ajax的post方式下载excel文件简单示例
2019/08/06 PHP
javascript 限制输入脚本大全
2009/11/03 Javascript
JQuery学习笔记 nt-child的使用
2011/01/17 Javascript
jQuery学习总结之jQuery事件
2014/06/30 Javascript
Javascript中设置默认参数值示例
2014/09/11 Javascript
微信js-sdk地理位置接口用法示例
2016/10/12 Javascript
Node.js 利用cheerio制作简单的网页爬虫示例
2018/03/01 Javascript
vue-loader中引入模板预处理器的实现
2019/09/04 Javascript
JS Generator 函数的含义与用法实例总结
2020/04/08 Javascript
浅谈React中组件逻辑复用的那些事儿
2020/05/21 Javascript
Javascript实现贪吃蛇小游戏(含详细注释)
2020/10/23 Javascript
微信小程序实现电影App导航和轮播
2020/11/30 Javascript
python中的随机函数小结
2018/01/27 Python
python写入已存在的excel数据实例
2018/05/03 Python
Windows系统下PhantomJS的安装和基本用法
2018/10/21 Python
python处理RSTP视频流过程解析
2020/01/11 Python
Python如何输出整数
2020/06/07 Python
Python2手动安装更新pip过程实例解析
2020/07/16 Python
Python文件操作及内置函数flush原理解析
2020/10/13 Python
python 爬虫之selenium可视化爬虫的实现
2020/12/04 Python
巴西24小时在线药房:Droga Raia
2020/05/12 全球购物
高级电工工作职责
2013/11/21 职场文书
创业融资计划书
2014/04/25 职场文书
教师暑期培训感言
2014/08/15 职场文书
教师业务学习材料
2014/12/16 职场文书
2015年社区中秋节活动总结
2015/03/23 职场文书
2016学习雷锋精神活动倡议书
2015/04/27 职场文书
五一晚会主持词
2015/07/01 职场文书
小学生安全教育心得体会
2016/01/15 职场文书
离婚协议书范本(2016最新版)
2016/03/18 职场文书
idea编译器vue缩进报错问题场景分析
2021/07/04 Vue.js
Anaconda安装pytorch和paddle的方法步骤
2022/04/03 Python