Spring事务大部分都是通过AOP实现的,所以事务失效的场景大部分都是因为AOP失效,AOP基于动态代理实现的
1.方法没有被public修饰
原因:Spring会为方法创建代理、AOP添加事务通知前提条件是该方法时public的。
2.类没有被Spring容器所托管
Spring没有办法给类生成动态代理
3.不正确的异常捕获
原因:事务通知只有捉到了目标抛出的异常,才能进行后续的回滚,如果目标自己处理异常,事务通知AOP无法捕捉到异常,不会进行回滚,事务失效。
4.在同一个类中的方法调用
a方法调用了当前对象中的b方法,没有调用代理对象的b方法
5.事务传播性设置有误
Spring有7种事务传播特性,其意义是确定多个具有事务控制的service相互调用时所形成的的事务边界,下表列出Spring的7种事务传播特性以及含义
传播特性 | 含义 |
---|---|
REQUIRED | Spring中默认的事务传播特效,表示必须存在事务,如果外层方法存在事务,则用外层方法的事务,否则开启一个新的事务 |
REQUIRES_NEW | 当前方法会开启一个新事物,如果外层方法存在事务,则会将外层方法的事务挂起,直到当前方法的事务提交或回滚才会恢复执行 |
SUPPORTS | 可以不存在事务,如果有事务则使用当前事务,没有则作为一个普通方法运行 |
NOT_SUPPORTED | 不会存在事务,如果外层方法有事务,则会挂起 |
MANDATORY | 强制事务执行,如果没有事务则抛异常 |
NEVER | 强制非事务执行,有事务就抛异常 |
NESTED | 如果外层方法存在事务,则创建一个保存点,如果当前方法没有异常,则统一到外层事务中提交,如果当前方法存在异常,则外层事务也会回滚,如果外层事务出现异常,只会回滚外层事务,当前方法不会回滚 |
6.rollback-for配置有误,通常是runtimeException需要回滚
7.没有配置事务管理器
默认自动配置,SSM项目中需要手动配置
8.数据库不支持事务
如果使用的数据库为MySQL,并且选用了MyISAM存储引擎,则Spring的事务就会失效。