Spring 的事务注解@Transactional失效的情况
1、@Transactional注解的方法内部调用了当前类中的方法,事务失效
解决方案:Spring事务注解失效之调用当前类方法
2、@Transactional注解只对方法的访问控制权限为pubic级别的才生效,其他级别的访问控制权限的方法事务失效
解决方案:@Transactional注解的方法声明为public的访问控制权限。
3、@Transactional注解的方法内部捕获并处理了异常时,事务失效
解决方案:将异常throw到@Transactional注解的方法的上级调用方法中处理。
4、抛出的异常不是Spring的事务支持的异常
Spring的事务只支持未检查异常(unchecked),不支持已检查异常(checked)。
Q:什么是未检查异常、已检查异常?
A:异常的继承结构:Throwable为基类,Error和Exception继承Throwable。Error和RuntimeException及其子类称为未检查异常(unchecked),其它异常称为已检查异常(checked)。
即下图中的蓝色部分是未检查异常,红色部分中Exception的除RuntimeException之外的其他子类是已检查异常。
需要注意的是,Spring事务只支持上面说的未检查异常,其他所有的异常的抛出都不会回滚。其中,开发过程中比较常见的就是SQLException。通过查看SQLException的继承关系可以看出,SQLException不属于未检查异常,所以SQLException的抛出不会导致事务回滚。
解决方案:
1、捕获异常,手动回滚。
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
参考:spring 事务控制 设置手动回滚
2、捕获异常,然后抛出一个事务支持回滚的异常。
常用的就是我们项目中会自定义异常继承自RuntimeException类,可以抛出这种自定义异常。
5、数据库不支持事务
MySQL数据库常用的引擎有MyISAM和InnoDB。
其中,MyISAM是不支持事务的,InnoDB是支持事务的。