• Spring多事务管理器报错处理


    报错如下

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    意思是出现两个事务管理器

    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 set
    		if (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;
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    由于我项目使用mybatis又使用了响应式变成的以来, 所以项目又两个事务管理器, 导致代码获取唯一bean报错

    如何解决

    首先我们要在defaultTransactionManager = this.beanFactory.getBean(TransactionManager.class);这行代码大断电, 然后使用idea计算
    ((DefaultListableBeanFactory)this.beanFactory).getBeansOfType(TransactionManager.class)
    计算结果是:

    "transactionManager" -> {JdbcTransactionManager@8195} 
    "connectionFactoryTransactionManager" -> {R2dbcTransactionManager@8197} 
    
    • 1
    • 2

    所以我们知道了我们事务管理器的beanName是transactionManager

    然后我们可以在@Transactional加上value值’transactionManager’, 问题解决

  • 相关阅读:
    rocketmq无法启动namesrv和broker
    librispeech 的train-clean-100--简单记录笔记
    人大与加拿大女王大学金融硕士——与其羡慕他人,不如充实自己
    .net webapi 实现 接口版本控制并打通swagger支持
    thinkphp6项目使用多应用开发
    算法实战:亲自写红黑树之四 插入insert的平衡
    【spring cloud】(二)服务的注册发现——Eureka
    【版本2020.03】使用idea导入maven项目
    【探索Linux】P.39(传输层 —— TCP的三次 “握手” 和四次 “挥手” )
    Unload data from Databend | 新手篇(4)
  • 原文地址:https://blog.csdn.net/yin18827152962/article/details/136383130