非public方法
默认情况下,只有
public
修饰的方法才能被
Spring
的事务管理器拦截,非
public
方法会被忽略。
@Transactional 是基于动态代理实现的,当创建 bean 实例时, Spring 框架会扫描带有@Transactional 注解的方法,并通过 AOP 技术生成代理对象并对事务进行管理。动态代理只能代理public 方法。
异常被捕获并处理了
如果在
@Transactional
注解标记的方法中,出现了异常但是该异常被捕获并处理了,并没有抛出异常,那么这个事务就会正常提交,而不是回滚。
抛出检查异常
Spring
默认只会回滚
非检查异常
(不指定
rollbackFor
参数的前提下)
- 非检查异常:在编译时不需要强制处理的异常。这些异常一般是由程序逻辑错误或者系统内部错误导致的
例如空指针异常(NullPointerException)、数组越界异常 (ArrayIndexOutOfBoundsException)等 - 检查异常:在编译时需要显式处理的异常。通常表示程序运行中可能出现的外部错误或不正常情况,通常表示程序运行中可能出现的外部错误或不正常情况
常见的检查异常包括IOException、SQLException等。
解决办法:
配置rollbackFor属性:@Transactional(rollbackFor=Exception.class)
没有开启事务注解支持
在
Spring Boot
项目中,需要在配置类上添加
@EnableTransactionManagement
注解来启用事务注解支持。
类内部调用@Transactional标注的方法
@Transactional 的实现原理在于以该注解为切面坐标,在扫描动态生成的代理类中以此坐标来在其前后分别设置事务开启和事务提交操作的增强,那么这些的前提是在于,你的操作环境是在于Spring 动态代理生成的代理类 中,而不是 this 对应的本类当一个 Bean 需要被注入其它 Bean 时, Spring 会创建一个代理对象来代替真正的 Bean 对象。这个代理对象会拦截目标 Bean 对象的方法调用,并在方法调用前后进行一些操作,比如实现事务管理、缓存处理等。这样,通过代理对象的调用,就可以实现一些横切关注点的统一处理。
解决方法