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 相关文章推荐
B/S开发中常用javaScript技术与代码
Mar 09 Javascript
不安全的常用的js写法
Sep 15 Javascript
jQuery-ui引入后Vs2008的无智能提示问题解决方法
Feb 10 Javascript
使用JQ来编写最基本的淡入淡出效果附演示动画
Oct 31 Javascript
AngularJS模块管理问题的非常规处理方法
Apr 29 Javascript
jquery动态遍历Json对象的属性和值的方法
Jul 27 Javascript
基于JavaScript实现带缩略图的轮播效果
Jan 12 Javascript
JS实现上传图片实时预览功能
May 22 Javascript
利用Decorator如何控制Koa路由详解
Jun 26 Javascript
vue中前进刷新、后退缓存用户浏览数据和浏览位置的实例讲解
Sep 21 Javascript
对angular4子路由&amp;辅助路由详解
Oct 09 Javascript
sharp.js安装过程中遇到的问题总结
Apr 02 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
PHP企业级应用之常见缓存技术篇
2011/01/27 PHP
解析:php调用MsSQL存储过程使用内置RETVAL获取过程中的return值
2013/07/03 PHP
php单链表实现代码分享
2016/07/04 PHP
PHP中in_array函数使用的问题与解决办法
2016/09/11 PHP
动态表单验证的操作方法和TP框架里面的ajax表单验证
2017/07/19 PHP
php ZipArchive实现多文件打包下载实例
2019/10/31 PHP
jQuery 学习第五课 Ajax 使用说明
2010/05/17 Javascript
JS基于clipBoard.js插件实现剪切、复制、粘贴
2016/05/03 Javascript
html中鼠标滚轮事件onmousewheel的处理方法
2016/11/11 Javascript
原生js获取left值和top值的三种方法
2017/08/02 Javascript
Bootstrap Tooltip显示换行和左对齐的解决方案
2017/10/11 Javascript
微信小程序实现预览图片功能
2020/10/22 Javascript
详解Vue用cmd创建项目
2019/02/12 Javascript
javascript数组常见操作方法实例总结【连接、添加、删除、去重、排序等】
2019/06/13 Javascript
vue如何使用async、await实现同步请求
2019/12/09 Javascript
vue从零实现一个消息通知组件的方法详解
2020/03/16 Javascript
详解小程序横屏方案对比
2020/06/28 Javascript
[02:32]DOTA2英雄基础教程 美杜莎
2014/01/07 DOTA
[41:37]DOTA2北京网鱼队选拔赛——冲击职业之路
2015/04/13 DOTA
python正则表达式判断字符串是否是全部小写示例
2013/12/25 Python
linecache模块加载和缓存文件内容详解
2018/01/11 Python
Python实现的连接mssql数据库操作示例
2018/08/17 Python
详解Python3除法之真除法、截断除法和下取整对比
2019/05/23 Python
pycharm 2019 最新激活方式(pycharm破解、激活)
2020/09/22 Python
python如何安装下载后的模块
2020/07/03 Python
Python configparser模块封装及构造配置文件
2020/08/07 Python
HTML5 离线应用之打造零请求、无流量网站的解决方法
2013/04/25 HTML / CSS
时装界的“朋克之母”:Vivienne Westwood
2017/07/06 全球购物
英国水族馆和池塘用品购物网站:Warehouse Aquatics
2019/08/29 全球购物
小学学雷锋活动总结
2014/04/25 职场文书
我读书我快乐演讲稿
2014/05/07 职场文书
党员干部对十八届四中全会的期盼
2014/10/17 职场文书
2014年服务员个人工作总结
2014/12/23 职场文书
2015年党风廉政建设目标责任书
2015/05/08 职场文书
领导干部学习心得体会
2016/01/23 职场文书
MySQL范围查询优化的场景实例详解
2022/06/10 MySQL