在项目中使用了两个事务管理器,因为项目中设计到两个数据库的操作,所以就声明了两个事务管理器;
但是在使用@Transactional注解的时候,没有手动指定事务要使用哪个,就有可能会导致事务不生效
案例:
1、在项目中,我用到了A和B两个数据库,所以,此时就需要声明两个事务管理器,我们假设命名为:ATransactionManager和BTransactionManager(这两个事务管理器,分别对应着A和B两个数据库就)
2、在使用的时候,如果当前方法中,都是对A数据库的表进行操作,那就需要在@Transactional注解的value属性上指定ATransactional
这里的aDataSource和bDataSource都是根据a和b两个数据库生成的,只需要在配置类中,加上这几行代码,spring在启动的时候,就会把这两个事务管理器放入到spring容器中
@Bean
public PlatformTransactionManager aTransactionManager() {
return new DataSourceTransactionManager(aDataSource());
}
@Bean
public PlatformTransactionManager bTransactionManager() {
return new DataSourceTransactionManager(bDataSource());
}
配置就完成了,这里,就和添加一个普通的bean对象是一样的,都会放到spring容器中
我遇到的问题是:我在一个方法上加了事务注解,但是没有指定value,实际上,这个接口中是要去操作a数据库的三张表,但是发现接口中事务回滚的时候,并没有把其他三张表的数据都回滚,debug看代码,也确实去执行了回滚的操作,最后发现是没有指定aTransactionManager的原因
源码解析
我们都知道,事务的源码,在
org.springframework.transaction.interceptor.TransactionInterceptor#invoke
org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
//根据事务属性获取获取事务管理器,这里一般是 DataSourceTransactionManager,我们也可以自己去指定事务管理器</