运用@Transactional抛出异常后不回滚
不回滚的情况有很多种,下面介绍几种常见的原因:
- 数据库配置问题
如果你使用的是mysql数据库,并且查看要回滚的表的引擎时,发现不是innodb的引擎,那么恭喜你,很可能是因为数据库表引擎的原因导致的,如果对mysql数据库引擎感兴趣的,可以参考以下文章
mysql数据库常用的引擎有两种(innodb和myisam),在建表时有些dba会默认使用myisam引擎,如果是这种引擎,那么在遇到异常时,数据库是不回滚的。所以将需要回滚的表引擎改为innodb。
解决方法:
ALTER TABLE tableName CHANGE TYPE=InnoDB;
- 抛出的异常类型的问题
如果你数据库的配置没有问题,那么基本是程序原因导致的没有回滚的问题。如果你使用的三大框架,很有可能是下面的问题导致的。
hibernate框架中,数据库事物的回滚默认只针对于抛到最外层的异常为
解决方法:
1.如果想要让框架允许自定义异常的回滚,需要将hibernate的配置文件增加如下配置:
<tx:advice
或者
定义不回滚的异常
<tx:advice
2.spring的事务边界是在调用业务方法之前开始的,业务方法执行完毕之后来执行commit
如:
try
}
}
由此可以推知,在spring中如果某个业务方法被一个
不过,如果在catch代码块中采用页面硬编码的方式使用spring
3.基于注解的事务:
回滚:
@Transactional(rollbackForClassName=”RuntimeException”)
@Transactional(rollbackForClassName={“RuntimeException”,”Exception”})
不回滚:
@Transactional(noRollbackFor=RuntimeException.class)
@Transactional(noRollbackFor={RuntimeException.class, Exception.class})