最近遇到了事务不回滚的情况,我还考虑说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事务异常回滚,捕获异常不抛出就不会回滚(转载) 解决了我一年前的问题的更多相关文章

  1. Spring事务异常回滚,捕获异常不抛出就不会回滚

    最近遇到了事务不回滚的情况,我还考虑说JPA的事务有bug? 我想多了.......    为了打印清楚日志,很多方法我都加tyr catch,在catch中打印日志.但是这边情况来了,当这个方法异常 ...

  2. 【转】Spring事务异常回滚,捕获异常不抛出就不会回滚

    最近遇到了事务不回滚的情况,我还考虑说JPA的事务有bug? 我想多了.......     为了打印清楚日志,很多方法我都加tyr catch,在catch中打印日志.但是这边情况来了,当这个方法异 ...

  3. spring事物回滚机制 (事务异常回滚,捕获异常不抛出就不会回滚)

    当异常被捕获catch的时候,spring的事物则不会回滚 为什么不会滚呢??  spring aop  异常捕获原理:被拦截的方法需显式抛出异常,并不能经任何处理,这样aop代理才能捕获到方法的异常 ...

  4. Spring事务异常回滚

    最近遇到了事务不回滚的情况,我还考虑说JPA的事务有bug? 我想多了.......    为了打印清楚日志,很多方法我都加tyr catch,在catch中打印日志.但是这边情况来了,当这个方法异常 ...

  5. 异常如果一直被throws抛出的话就会被jvm异常处理器处理了

    异常如果一直被throws抛出的话就会被jvm异常处理器处理了,这时jvm会跳出正常运行状态. 异常如果一直被throws抛出的话就会被jvm异常处理器处理了,这时jvm会跳出正常运行状态. 异常如果 ...

  6. spring事务 异常回滚

    spring事务回滚 可抛出自定义继承自RuntimeException

  7. Spring事务异常rollback-only

    转自:https://blog.csdn.net/sgls652709/article/details/49472719 前言 在利用单元测试验证spring事务传播机制的时候出现了下面的异常: Tr ...

  8. Spring事务异常rollback-only 笔记

    造成以上异常的原因情形: 在spring里面我们配置了事务的传播机制是REQUIRED,所以这两个事务最终会合并成一个事务.当a方法调用b方法时,程序中a方法中由于某某原因导致抛出异常(或者明确将该事 ...

  9. hibernate整合spring事务异常

    Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushM ...

随机推荐

  1. [置顶] Codeforces Round #190 (Div. 2)(完全)

    好久没有写博客了,一直找不到有意义的题可以写,这次也不算多么有意义,只是今天是比较空的一天,趁这个时候写一写. A. B. 有一点贪心,先把每个拿去3的倍数,余下0或1或2,然后三个一起拿. 对于以上 ...

  2. HDU 1757 A Simple Math Problem(矩阵高速幂)

    题目地址:HDU 1757 最终会构造矩阵了.事实上也不难,仅仅怪自己笨..= =! f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + -- + a9 ...

  3. flexigrid 修改json格式

    1.修改默认的json格式为key:value 修改前 rows: [{id:'ZW',cell:['ZW','ZIMBABWE','Zimbabwe','ZWE','716']},{id:'ZW', ...

  4. Hibernate征途(三)之CRUD

    上篇博客<Hibernate征途(二)之基础与核心>介绍了Hibernate的基础内容和核心内容,这篇博客简单实践一下.第一篇博客也说过Hibernate是一种JDBC的简化方案,既然是和 ...

  5. CSS Transform让百分比宽高布局元素水平垂直居中

    很早以前了解过当元素是固定宽度和高度的时候,水平垂直高居中的方法可以设置margin的负值来使其居中,这个负值是元素的宽和高的一半,比如宽高是100px,那么就用margin-left:-50px;m ...

  6. taobao面试要点

    第一: 其中有几个点必问,JVMGC深层机制.类加载,包括Tomcat和Jboss的.线程相关的如离线锁,互斥同步,java主线程和工作线程机制,concurrent包下的锁和sync关键字一些区别, ...

  7. MVC3学习随记一

    最近才接触mvc,也是才接触linq语法,还有EntiyFramework,个人感觉这种开发模式还是挺不错的,随手记点笔记,简单做个增删改查吧 一.实例化上下文ObjectContext: 引用空间那 ...

  8. 解决 Boot Camp 虚拟机升级到 Windows 10 后 Parallels Desktop 不能识别的问题

    最近几天 Win10 正式版开始推送了,对于喜欢折腾的博主,在第一时间就把 Mac 中 Boot Camp 从 Win7 升级到 Win10,初步体验还不错,等博主用过一段时间之后,再来给大家分享使用 ...

  9. NSDate 的一些操作(比较、创建、在现有date加减一定时间等)

    创建当前时间 NSDate *date = [NSDate date]; 从现在开始的24小时 NSTimeInterval a_day = 24*60*60; NSDate *tomorrow = ...

  10. effective c++ 条款06 不想自动生成函数,就明确拒绝

    编辑器会主动的生成三个/五个函数,如果不需要我们应该主动拒绝 使用私有属性来拒绝 ``` include int main() { return 0; } ``` 使用继承的方式来拒绝