查阅资料:当@Transactional不起作用如何排查问题。
可以按照以下几个步骤逐一确认:
1、首先要看数据库本身对应的库、表所设置的引擎是什么。MyIsam不支持事务,如果需要,则必须改为InnnoDB。
2、@Transactional所注解的方法是否为public
3、@Transactional所注解的方法所在的类,是否已经被注解@Service或@Component等。
4、需要调用该方法,且需要支持事务特性的调用方是在在 @Transactional所在的类的外面。注意:类内部的其他方法调用这个注解了@Transactional的方法,事务是不会起作用的。
5、注解为事务范围的方法中,事务的回滚仅仅对于unchecked的异常有效。对于checked异常无效。也就是说事务回滚仅仅发生在出现RuntimeException或Error的时候。
unchecked:不受检异常或错误一般有RuntimeException或Error
checked:Exception及其子类
其实RuntimeException也是Exception的子类,但是runtimeException 是运行时异常,必须处理的, 还有编译时异常,不处理编译都过不去
如果希望一般的异常也能触发事务回滚,需要在注解了@Transactional的方法上,将@Transactional回滚参数设为:
@Transactional(rollbackFor=Exception.class)
6、非springboot项目,需要检查spring配置文件xml中:
(1)扫描包范围是否配置好,否则不会在启动时spring容器中创建和加载对应的bean对象。
(2)事务是否已经配置成开启
7、springboot项目有两个可选配置,默认已经支持事务了,可以写也可以不写。
(1)在启动类上加这个注解开启事务管理
@EnableTransactionManagement
(2)在配置文件中可以配置上失败回滚:
spring:
transaction:
rollback-on-commit-failure:true
由于本人比较菜,这个事务的问题我纠结了半天,为什么我完全符合上述要求但是事务就是不起作用呢???
答:因为我是多数据源。在查看资料后,(根据我的理解)在启动类开始事务管理后,因为是多数据源,所以会产生多个事务管理对象对应每一个数据源,在我们使用@Transaction去修饰方法的时候spring并不知道使用的是哪个事务管理器,所以我们需要给他指定事务管理器,这个名字和数据源对象bean相同
@Override
@Transactional(transactionManager = "secondaryDataSourceTransactionManager")
public void test() {}
@Bean(name = "secondaryDataSource")
@Qualifier("secondaryDataSource")
@ConfigurationProperties(prefix="spring.datasource.druid.secondary")
public DataSource secondaryDataSource() {
return DruidDataSourceBuilder.create().build();
}
@Bean(name = "secondaryDataSourceTransactionManager")
public DataSourceTransactionManager secondary(@Qualifier("secondaryDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
可以参考:
https://blog.csdn.net/qq_36138324/article/details/81611935
(侵权可联系删除)
try catch之后要手动回滚
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
spring事务七大传播特性
1、支持当前事务:
2、不支持当前事务:
3、其他
四大隔离级别
读未提交,读已提交,可重复读(mysql),串行化