java事务回滚失败问题分析
Spring-Java事物回滚失效处理最近在做项目中,无意间发现有个类在抛事物回滚操作,数据也正常的插入到数据库当中了,于是仔细查看看一下具体原因。
一切还是要从Java的检查型异常和非检查型异常说起。
那么什么是检查型异常什么又是非检查型异常呢?
最简单的判断点有两个:
1.继承自RuntimeException或Error的是非检查型异常,而继承自Exception的则是检查型异常(当然,RuntimeException本身也是Exception的子类)。
2.对非检查型类异常可以不用捕获,而检查型异常则必须用try……catch语句块进行处理或者把异常交给上级方法处理,总之就是必须写代码处理它。
Java的异常结构如下图。其中直接继承Exception的异常,必须捕获,属于检查型异常。
再回过来看我的代码:
1、方法名前面有
@Transactional
2、Spring的配置文件applicationContext-XXX.xml当中也有Spring事物的相关配置
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> <property name="rollbackOnCommitFailure" value="true"></property> </bean>
但是为什么在Service层方法调用的时候,try……catch抛Exception异常已经提交的事物却没有回滚?
查看相关spring的文档后发现,原来spring声明式事务管理默认对非检查型异常和运行时异常进行事务回滚,而对检查型异常则不进行回滚操作。
代码中try……catch抛出的Exception异常,属于检查型异常,Spring的框架默认是不会进行回滚的。
在编程中对非检查型类异常可以不用捕获,而检查型异常则必须用try语句块进行处理或者把异常交给上级方法处理总之就是必须写代码处理它。
所以必须在service捕获异常,然后再次手动throw一个非检查型异常,这样事务方才起效。例如:
try{ ………… } catch (Exception e) { ………… throw new BusinessException(e.getMessage()); }
当然我们还有更简便的方法来解决这个问题,那就是通过注解参数改变默认的回滚方式。
在@Transaction注解中定义了noRollbackFor和RollbackFor来指定某种异常是否回滚。
使用例:
@Transaction(noRollbackFor=RuntimeException.class)
@Transaction(RollbackFor=Exception.class)
所以上述的问题可以直接将@Transaction添加回滚参数@Transaction(RollbackFor=Exception.class),这样就改变了默认的事务处理方式。
启示:
这就要求我们在自定义异常的时候,让自定义的异常继承自RuntimeException,这样抛出的时候才会被Spring默认的事务处理准确处理。
总结
以上就是本文关于java事务回滚失败问题分析的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!
相关文章
SpringBoot+Dubbo+Seata分布式事务实战详解
这篇文章主要介绍了SpringBoot+Dubbo+Seata分布式事务实战详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2019-07-07Java+Spring+MySql环境中安装和配置MyBatis的教程
这篇文章主要介绍了Java+Spring+MySql环境中安装和配置MyBatis的教程,MyBatis一般被用来增强数据库操作,文中对MyBatis的主配置文件有较为详细的讲解,需要的朋友可以参考下2016-04-04SpringCloud2020 bootstrap 配置文件失效的解决方法
这篇文章主要介绍了SpringCloud2020 bootstrap 配置文件失效的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2021-02-02Spring Boot使用RestTemplate消费REST服务的几个问题记录
这篇文章主要介绍了Spring Boot使用RestTemplate消费REST服务的几个问题记录,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧2018-06-06浅谈spring-boot 允许接口跨域并实现拦截(CORS)
本篇文章主要介绍了浅谈spring-boot 允许接口跨域并实现拦截(CORS),具有一定的参考价值,有兴趣的可以了解一下2017-08-08Mybatis 动态sql if 判读条件等于一个数字的案例
这篇文章主要介绍了Mybatis 动态sql if 判读条件等于一个数字的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2020-11-11
最新评论