spring-Java事物回滚失效处理最近在做项目中,无意间发现有个类在抛事物回滚操作,数据也正常的插入到数据库当中了,于是仔细查看看一下具体原因。

一切还是要从Java的检查型异常和非检查型异常说起。

那么什么是检查型异常什么又是非检查型异常呢?

 最简单的判断点有两个:

    1.继承自RuntimeException或Error的是非检查型异常,而继承自Exception的则是检查型异常(当然,RuntimeException本身也是Exception的子类)。

    2.对非检查型类异常可以不用捕获,而检查型异常则必须用try……catch语句块进行处理或者把异常交给上级方法处理,总之就是必须写代码处理它。

Java 的异常结构如下图。其中直接继承Exception的异常,必须捕获,属于检查型异常。

再回过来看我的代码:

1、方法名前面有

  1. @Transactional

2、Spring的配置文件applicationContext-XXX.xml当中也有Spring事物的相关配置

  1. <bean id="transactionManager"
  2. class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  3. <property name="dataSource" ref="dataSource" />
  4. <property name="rollbackOnCommitFailure" value="true"></property>
  5. </bean>

但是为什么在Service层方法调用的时候,try……catch抛Exception异常已经提交的事物却没有回滚?

查看相关spring的文档后发现,原来spring声明式事务管理默认对非检查型异常和运行时异常进行事务回滚,而对检查型异常则不进行回滚操作。

代码中try……catch抛出的Exception异常,属于检查型异常,Spring的框架默认是不会进行回滚的。

在编程中对非检查型类异常可以不用捕获,而检查型异常则必须用try语句块进行处理或者把异常交给上级方法处理总之就是必须写代码处理它。

所以必须在service捕获异常,然后再次手动 throw 一个非检查型异常,这样事务方才起效。例如:

  1. try{
  2. …………
  3. } catch (Exception e) {
  4. …………
  5. throw new BusinessException(e.getMessage());
  6. }

或者

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

当然我们还有更简便的方法来解决这个问题,那就是通过注解参数改变默认的回滚方式 。

在@Transaction注解中定义了noRollbackFor和RollbackFor来指定某种异常是否回滚。

使用例:

@Transaction(noRollbackFor=RuntimeException.class)

@Transaction(RollbackFor=Exception.class)

所以上述的问题可以直接将@Transaction添加回滚参数@Transaction(RollbackFor=Exception.class) ,这样就改变了默认的事务处理方式。

启示 :

这就要求我们在自定义异常的时候,让自定义的异常继承自RuntimeException,这样抛出的时候才会被Spring默认的事务处理准确处理。

Spring-Java事物回滚失效处理的更多相关文章

  1. spring的事物回滚

    //默认spring只能在捕获到runtimeException时才会回滚, throw new RuntimeException("出现runtime异常"); } catch ...

  2. Spring aop切面插入事物回滚

    <!-- tx标签配置 事物--> <tx:advice id="txadvice" transaction-manager="transactionM ...

  3. Spring事务不回滚原因分析

    Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离. 在我完成一个项目的时候,遇到了一个Spring事务不回滚的问题,通过aspectJ和@Transacti ...

  4. Spring事务管理——回滚(rollback-for)控制

    探讨Spring事务控制中,异常触发事务回滚原理.文章进行了6种情况下的Spring事务是否回滚. 以下代码都是基于Spring与Mybatis整合,使用Spring声明式事务配置事务方法. 1.不捕 ...

  5. msql,触发器无事物回滚,插入之前满足条件再插入

    很少写mysql的触发器和存储过程,由于需要需要做一个很小的判断,要用到触发器,要达到的效果就是,插入之前判断是否满足条件如果不满足就不插入 如果用sqlserver 或者orcale 就很简单,按s ...

  6. 复习课程jdbc:使用配置文件properties进行连接数据库,数据库存取图片,批处理,时间戳,事物回滚等等

    使用配置文件properties进行连接数据库 首先创建一个file自定义文件名,但是后缀名必须改为.properties(不分大小写):如config.properties: 然后双击config. ...

  7. springboot事物回滚

    要添加事物 必须在方法上添加 @Transactional 注解 如果需要事物回滚有两个条件 1.方法中有异常或者主动抛异常 2.主动去回滚 TransactionAspectSupport.curr ...

  8. peewee 事物 回滚

    peewee 事物 回滚 #!/usr/bin/env python # coding=utf-8 from peewee import * db = MySQLDatabase(host='123. ...

  9. C#里面的事物回滚,解决同步数据插入时出现重复数据

    什么是事物回滚: 举个栗子,你在你家的银行分行取钱,取完钱数据要同步,而且可能每个分行都有一个存储这些数据的数据库,分行的这些 存取的记录都需要实时同步,如果你取完500刚好断电了,好嘛,分行可能刚记 ...

随机推荐

  1. shell基本认识

    shell基本认识 bash # echo $BASH /bin/bash 第一个shell脚本first_shell.sh #!/bin/bash echo "Hello world!&q ...

  2. Memcached stats sizes 命令

    Memcached stats sizes 命令用于显示所有item的大小和个数. 该信息返回两列,第一列是 item 的大小,第二列是 item 的个数. 语法: stats sizes 命令的基本 ...

  3. jQuery回车键快速切换下一个input文本框解决方案

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. STOMP协议规范【转】

    STOMP协议规范英文原文:http://stomp.github.io/stomp-specification-1.2.html STOMP协议规范译文原文:http://simlegate.com ...

  5. 格雷码C++实现

    格雷码C++实现 题目 给定一个整数n,请返回n位的格雷码,顺序从0开始,要求递归实现. 格雷码: 在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,则称这种编码为格雷码(Gray Code ...

  6. 奇怪的表达式求值 (java实现)

    题目参考:http://blog.csdn.net/fuxuemingzhu/article/details/68484749 问题描述; 题目描述: 常规的表达式求值,我们都会根据计算的优先级来计算 ...

  7. HDU1595-最短路-删边

    find the longest of the shortest Time Limit: 1000/5000 MS (Java/Others)    Memory Limit: 32768/32768 ...

  8. linux---网络相关配置,ssh服务,bash命令及优先级,元字符

    - 二:临时配置网络(ip,网关,dns)+永久配置 临时配置: [root@nfs-server ~]# ifconfig ens32: flags=4163<UP,BROADCAST,RUN ...

  9. RabbitMQ消息队列(九)RPC开始应用吧

    一 简单应用 RPC——远程过程调用,通过网络调用运行在另一台计算机上的程序的函数\方法,是构建分布式程序的一种方式.RabbitMQ是一个消息队列系统,可以在程序之间收发消息.利用RabbitMQ可 ...

  10. 010PHP基础知识——运算符(三)

    <?php /** * 位运算符: * 1:&按位与:左右两边的数,同位都为1,返回是1,否则返回是0 */ /*$a = 5; $b = 6; $a = decbin($a);//10 ...