报错如下
Description:Field defaultUidGenerator in len.hgy.wsearch.interfaces.search.api.CityController required a single bean, but 2 were found:- transactionManager: defined by method 'transactionManager' in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfiguration$JdbcTransactionManagerConfiguration.class]- connectionFactoryTransactionManager: defined by method 'connectionFactoryTransactionManager' in class path resource [org/springframework/boot/autoconfigure/r2dbc/R2dbcTransactionManagerAutoConfiguration.class]This may be due to missing parameter name information
意思是出现两个事务管理器
TransactionAspectSupport#determineTransactionManager
org.springframework.transaction.interceptor.TransactionAspectSupport#determineTransactionManager
这个是获取事务管理器的类, 在需要事务时候从这里获取(事务会包含数据源, 有缓存,提高性能)
protected TransactionManager determineTransactionManager(@Nullable TransactionAttribute txAttr) {// Do not attempt to lookup tx manager if no tx attributes are setif (txAttr == null || this.beanFactory == null) {return getTransactionManager();}// 这个qualifier 其实就是@Transactional注解的value或者transactionManager的值, 作为bean名称String qualifier = txAttr.getQualifier();if (StringUtils.hasText(qualifier)) {return determineQualifiedTransactionManager(this.beanFactory, qualifier);} // 如果指定了管理器的bean名称, 就使用bean名称获取else if (StringUtils.hasText(this.transactionManagerBeanName)) {return determineQualifiedTransactionManager(this.beanFactory, this.transactionManagerBeanName);}else {TransactionManager defaultTransactionManager = getTransactionManager();if (defaultTransactionManager == null) {defaultTransactionManager = this.transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY);if (defaultTransactionManager == null) {defaultTransactionManager = // 默认是更具TransactionManagerc的class类型获取this.beanFactory.getBean(TransactionManager.class);this.transactionManagerCache.putIfAbsent(DEFAULT_TRANSACTION_MANAGER_KEY, defaultTransactionManager);}}return defaultTransactionManager;}}
由于我项目使用mybatis又使用了响应式变成的以来, 所以项目又两个事务管理器, 导致代码获取唯一bean报错
如何解决
首先我们要在defaultTransactionManager = this.beanFactory.getBean(TransactionManager.class);
这行代码大断电, 然后使用idea计算
((DefaultListableBeanFactory)this.beanFactory).getBeansOfType(TransactionManager.class)
计算结果是:
"transactionManager" -> {JdbcTransactionManager@8195}
"connectionFactoryTransactionManager" -> {R2dbcTransactionManager@8197}
所以我们知道了我们事务管理器的beanName是transactionManager
然后我们可以在@Transactional加上value值’transactionManager’, 问题解决