Spring事务异常回滚,捕获异常不抛出就不会回滚(转载) 解决了我一年前的问题
最近遇到了事务不回滚的情况,我还考虑说JPA的事务有bug? 我想多了.......
为了打印清楚日志,很多方法我都加tyr catch,在catch中打印日志。但是这边情况来了,当这个方法异常时候 日志是打印了,但是加的事务却没有回滚。
例:
类似这样的方法不会回滚 (一个方法出错,另一个方法不会回滚) :
- if(userSave){
- try {
- userDao.save(user);
- userCapabilityQuotaDao.save(capabilityQuota);
- } catch (Exception e) {
- logger.info("能力开通接口,开户异常,异常信息:"+e);
- }
- }
下面的方法回滚(一个方法出错,另一个方法会回滚):
- if(userSave){
- try {
- userDao.save(user);
- userCapabilityQuotaDao.save(capabilityQuota);
- } catch (Exception e) {
- logger.info("能力开通接口,开户异常,异常信息:"+e);
- throw new RuntimeException();
- }
- }
或者:
- if(userSave){
- try {
- userDao.save(user);
- userCapabilityQuotaDao.save(capabilityQuota);
- } catch (Exception e) {
- logger.info("能力开通接口,开户异常,异常信息:"+e);
- TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
- }
- }
为什么不会滚呢??是对Spring的事务机制就不明白。!!
默认spring事务只在发生未被捕获的 runtimeexcetpion时才回滚。
spring aop 异常捕获原理:被拦截的方法需显式抛出异常,并不能经任何处理,这样aop代理才能捕获到方法的异常,才能进行回滚,默认情况下aop只捕获runtimeexception的异常,但可以通过
配置来捕获特定的异常并回滚
换句话说在service的方法中不使用try catch 或者在catch中最后加上throw new runtimeexcetpion(),这样程序异常时才能被aop捕获进而回滚
解决方案:
方案1.例如service层处理事务,那么service中的方法中不做异常捕获,或者在catch语句中最后增加throw new RuntimeException()语句,以便让aop捕获异常再去回滚,并且在service上层(webservice客户端,view层action)要继续捕获这个异常并处理
方案2.在service层方法的catch语句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句,手动回滚,这样上层就无需去处理异常(现在项目的做法)
参考博客 Spring事务管理只对出现运行期异常进行回滚 http://blog.csdn.net/abc19900828/article/details/39497631
spring事物传播机制和隔离级别 http://blog.csdn.net/hijiankang/article/details/9174461
spring事务处理详解 http://blog.csdn.net/u013628152/article/details/47980811
1:Java包含两种异常:checked异常和unchecked异常。
checked和unchecked异常之间的区别是:
Checked异常必须被显式地捕获try-catch-finally,而unchecked异常则可以不必捕获或抛出。
Checked异常继承java.lang.Exception类。Unchecked异常继承自java.lang.RuntimeException类。
2:Mysql 存储引擎中InnoDB与Myisam的主要区别
事务处理方面:innodb 支持事务功能,myisam 不支持。
Myisam 的执行速度更快,性能更好。
engine = innodb 和 engine = myisam
可使用下述语句之一检查表的表类型:
SHOW TABLE STATUS LIKE ‘tbl_name’;
SHOW CREATE TABLE tbl_name;
使用下述语句,可检查mysqld服务器支持的存储引擎:
SHOW ENGINES;
3:spring事务处理
throw new RuntimeException(“xxxxxxxxxxxx”); 默认事务回滚
throw new Exception(“xxxxxxxxxxxx”); 默认事务不回滚
Spring的AOP即声明式事务管理默认是针对unchecked exception回滚。也就是默认对RuntimeException()异常或是其子类进行事务回滚;
checked异常,throw new Exception默认不会回滚
若想让checked异常或者自定义异常回滚
(1)配置文件方式
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="update*" no-rollback-for="IOException"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" rollback-for="com.cn.untils.exception.MyException"/>
</tx:attributes>
</tx:advice>
(2)注解方式
@Transactional(rollbackFor = Exception.class)
@Transactional(rollbackFor = MyException.class)
不起作用:
@Transactional
public void addAdmin(Admin admin) throws Exception {
try {
this.adminDao.add(admin);
admin.setUsername("123456789012345");
this.adminDao.update(admin);
} catch (Exception e) {
e.printStackTrace();
throw new Exception("测试!");
}
}
起作用
@Transactional(rollbackFor = Exception.class)
public void addAdmin(Admin admin) throws Exception {
try {
this.adminDao.add(admin);
admin.setUsername("123456789012345");
this.adminDao.update(admin);
} catch (Exception e) {
e.printStackTrace();
throw new Exception("测试!");
}
}
起作用
@Transactional
public void addAdmin(Admin admin) {
try {
this.adminDao.add(admin);
admin.setUsername("123456789012345");
this.adminDao.update(admin);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("测试!");
}
}
完整写法:
@Transactional(rollbackFor = RuntimeException.class)
public void addAdmin(Admin admin) {
try {
this.adminDao.add(admin);
admin.setUsername("123456789012345");
this.adminDao.update(admin);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("测试!");
}
Spring事务异常回滚,捕获异常不抛出就不会回滚(转载) 解决了我一年前的问题的更多相关文章
- Spring事务异常回滚,捕获异常不抛出就不会回滚
最近遇到了事务不回滚的情况,我还考虑说JPA的事务有bug? 我想多了....... 为了打印清楚日志,很多方法我都加tyr catch,在catch中打印日志.但是这边情况来了,当这个方法异常 ...
- 【转】Spring事务异常回滚,捕获异常不抛出就不会回滚
最近遇到了事务不回滚的情况,我还考虑说JPA的事务有bug? 我想多了....... 为了打印清楚日志,很多方法我都加tyr catch,在catch中打印日志.但是这边情况来了,当这个方法异 ...
- spring事物回滚机制 (事务异常回滚,捕获异常不抛出就不会回滚)
当异常被捕获catch的时候,spring的事物则不会回滚 为什么不会滚呢?? spring aop 异常捕获原理:被拦截的方法需显式抛出异常,并不能经任何处理,这样aop代理才能捕获到方法的异常 ...
- Spring事务异常回滚
最近遇到了事务不回滚的情况,我还考虑说JPA的事务有bug? 我想多了....... 为了打印清楚日志,很多方法我都加tyr catch,在catch中打印日志.但是这边情况来了,当这个方法异常 ...
- 异常如果一直被throws抛出的话就会被jvm异常处理器处理了
异常如果一直被throws抛出的话就会被jvm异常处理器处理了,这时jvm会跳出正常运行状态. 异常如果一直被throws抛出的话就会被jvm异常处理器处理了,这时jvm会跳出正常运行状态. 异常如果 ...
- spring事务 异常回滚
spring事务回滚 可抛出自定义继承自RuntimeException
- Spring事务异常rollback-only
转自:https://blog.csdn.net/sgls652709/article/details/49472719 前言 在利用单元测试验证spring事务传播机制的时候出现了下面的异常: Tr ...
- Spring事务异常rollback-only 笔记
造成以上异常的原因情形: 在spring里面我们配置了事务的传播机制是REQUIRED,所以这两个事务最终会合并成一个事务.当a方法调用b方法时,程序中a方法中由于某某原因导致抛出异常(或者明确将该事 ...
- hibernate整合spring事务异常
Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushM ...
随机推荐
- Pet(dfs+vector)
Pet Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- cmd命令大全/cmd命令提示符大全
刚接触电脑的时候是从DOS系统开始,DOS时代根本就没有Windows这样的视窗操作界面,只有一个黑漆漆的窗口,让你输入命令.所以学DOS系统操作,cmd命令提示符是不可或缺的.可以告诉大家,大多数的 ...
- 使用View Model从表现层分离领域模型
本文来自:http://www.cnblogs.com/shanyou/archive/2010/04/03/1703501.html Model-View-Controller(模型-视图-控制器, ...
- C# 3.0 { get; set; } 默认值
.NET Framework 3.5 使用的是 C# 3.0,C# 3.0 有一些新的语言特性,其中有一项就是快捷属性. 之前的写法: private int _id = 0;public int I ...
- how to translate the text of push button
Background:In a project, the need to translate the buttons on the screen, as shown below,the followi ...
- IBM WebSphere MQ的C#工具类以及源码(net)
简单的介绍一下MQ常用的对象 Queue Manager 队列管理器 主要负责管理队列.通道等,类似与Oracle中的Oracle实例的概念,在一台服务器中可以定义多个Queue Manager. Q ...
- easyui combo自动高度(下拉框空白问题)
设置.combo-panel {max-height:200px;} 在用到easyui-combobox时,设置panelHeight:'auto'
- DRBD脑裂解决方法
1.查看主服务器 [root@master ~]# /etc/init.d/drbd status drbd driver loaded OK; device status: version: (ap ...
- 关于Eclipse的编码配置和字体大小设置
编码设置 1.工作空间编码:Window-->Preferences-->General-->Workspace 2.工程文件编码:项目-->Properties-->R ...
- Which PHP mode? Apache vs CGI vs FastCGI
Which PHP mode? Apache vs CGI vs FastCGI There are multiple ways to execute PHP scripts on a web ser ...