1、数据库本身不支持事务
比如 mysql 数据库使用了MyISAM存储引擎时,由于MyISAM引擎本身不支持事务,所以所有的数据库操作都不支持事务
2、未启用事务功能
在Spring中,要启用事务功能,需要配置事务管理器 ,并配合Spring AOP指定需要开启事务的方法,或者开启事务注解功能,使用@Transactional注解来指定需要开启事务的方法
1、JDBC事务:org.springframework.jdbc.datasource.DataSourceTransactionManager,比如常用的Mybatis框架
2、Hibernate事务:org.springframework.orm.hibernate5.HibernateTransactionManager,如果项目中使用了Hibernate作为持久化框架,则需要配置该事务管理器
Java持久化API事务(JPA):org.springframework.orm.jpa.JpaTransactionManager,同样,如果项目中使用的是JPA作为持久化框架,那么需要配置该事务管理器
Java原生API事务:org.springframework.transaction.jta.JtaTransactionManager,适应与分布式事务,不管是jdbc、hibernate还是Mybatis,都可以通过JtaTransactionManager来配置分布式事务
3、事务传播类型配置不正确
1、NOT_SUPPORTED:不支持事务,如果当前存在事务则挂起。事务嵌套时,若发生异常,NOT_SUPPORTED类型的事务方法中已执行的数据更改不会回滚,外层事务正常回滚
2、REQUIRES_NEW:创建一个新的事务,若当前存在事务则挂起。事务嵌套时,若REQUIRES_NEW类型事务执行完成后发生异常,在该事务中执行的数据更改不会回滚,因为事务已提交,外层事务正常回滚
3、SUPPORTS:支持事务,若不存在事务则以非事务执行。
4、在非事务方法中调用事务方法
首先Spring事务管理是基于AOP动态代理实现的,在执行目标方法前后进行事务的开启、提交或回滚操作,所有如果目标方法没有添加事务,则不走事务
1、在一个非事务方法中调用本类的事务方法(自身调用),若发生异常,则已执行的数据更改不会回滚
2、在一个非事务方法中调用另一个类的事务方法,若本类发生异常,则已执行的数据更改不会回滚,若事务方法发送异常,则事务方法回滚,本类已执行的数据更改不会回滚
5、进行了 try catch 异常捕获,并未抛出异常
在事务方法中,使用try catch捕获了异常且没有抛出异常,在代理类中因无法捕获异常而不能正常回滚
PS:捕获异常后重新抛出异常,可正常回滚。
6、指定了事务回滚异常 rollbackFor
指定了事务回滚异常后,若发生的异常不是指定异常或子类异常时,事务不回滚。默认:RuntimeException或者Error及其子类