在 使用spring 对我们的项目进行管理,使用的到事务的场景非常多,但是有时候,一些问题会导致事务的失效。
在此对spring管理的事务失效的情况进行分析》
1.可能数据库方面,并不支持事务,采用的是非innoDB的引擎。MyISAM 不支持事务管理。查看数据库的数据库引擎
2.配置文件的问题。可能没有给数据库添加对应的事务管理,对应的没有配置transactionManager
3.可能存在自身调用自身的情况 也就是this的调用。
public void 。。。(。。。) {
this.save(....);
}
@Transactional
public void save(....) {
asdasdasdasdasd
}
@Transactional
public void 。。。(。。。) {
this.save(....);
}
@Transactional
public void save(....) {
asdasdasdasdasd
}
这两种调用的方式,都会导致事务的失效,对应的事务并不会回滚。
4.可能对应的bean 并没有让spring进行管理,可能没有添加对应的 service注解,或者在对应的xml中没有对应的bean 的配置
5.现在流行的restful风格的,统一的返回格式,我们会自己处理对应的异常。自己把对应的异常进行catch,导致的问题是,spring的代理对象没有起到作用,导致事务没有回滚,看我以前的文章https://blog.csdn.net/drsbbbl/article/details/103033983
6.可能对应的异常级别不正确。因为默认情况下。spring对异常的管理 级别是runtimeException 当我们在catch的时候,自己返回的异常 比如 throw new Exception(e) 导致事务失效。可以这样设置对用的异常级别 @Transactional(rollbackFor = Exception.class)
7.方法的修饰符 不是public
摘自微信文章
以下来自 Spring 官方文档:
When using proxies, you should apply the @Transactional annotation only to methods with public visibility. If you do annotate protected, private or package-visible methods with the @Transactional annotation, no error is raised, but the annotated method does not exhibit the configured transactional settings. Consider the use of AspectJ (see below) if you need to annotate non-public methods.
大概意思就是 @Transactional
只能用于 public 的方法上,否则事务不会失效,如果要用在非 public 方法上,可以开启 AspectJ
代理模式。
8. 以非事务的方式进行事务管理 @Transactional(propagation = Propagation.NOT_SUPPORTED)
9.可能定义切点的时候,定义的切点对象不正确。比如:execution(* com.edu.spring.aop..*.add*(..))
可能切入点为 add开头的,但是你的方法是saveOrder 这样也会导致事务失效。
部分转载:栈长 Java技术栈