多数据源注解事务异常 found 2:anyline.transaction

最后更新:2024-01-31 14:33:48 | 状态:未完成
在多数据源情况下,通过注解控制事务会报这个异常
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [TransactionManager] is defined: expected single matching bean but found 2:anyline.transaction.a,anyline.transaction.b
报这个异常的意思是,spring需要注入一个事务控制器,但是在上下文中找到了两个事务控制器,所以不知道应该用哪个了

解决方式:
如果只在默认数据源中启于事务,可以指定一个主事务管理器,
  1. 在注解上明确指定事务管理器
    @Transactional(value = "transactionManager")
  2. 如果动态数据源不需要事务,这样最简单:把ConfigTable.IS_OPEN_TRANSACTION_MANAGER = false 禁用针对anyline创建的数据源的事务管理器
  3. 在项目中注册一个@Primary注解的事务管理器
  4. 与2类似,让anyline提供一个与@Primary类似的事务管理器
    如果配置文件中有默认数据源,开启ConfigTable.IS_OPEN_PRIMARY_TRANSACTION_MANAGER=true
  5. 显式创建一个事务管理器
    调用DataSourceHolder.regTransactionManager("primary", datasource, true); datasources:数据源或数据源bean.name
如果多个数据源都需要控制事务,参考【多数据源事务控制
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.transaction.TransactionManager' available: expected single matching bean but found 4: transactionManager,anyline.transaction.company,anyline.transaction.receive,anyline.transaction.chanye_report

at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1273)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveBean(DefaultListableBeanFactory.java:494)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:349)

at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342)

at org.springframework.transaction.interceptor.TransactionAspectSupport.determineTransactionManager(TransactionAspectSupport.java:503)

简单了解一下注释事务的执行过程。
1.在方法执行前,检测到@Transactional注解,启动事务。
普通的事务是基础连接之上,需要需要确定是针对哪个连接启动事务,这里是通过事务管理器来实现的,所以这时需要获取到事务管理器,默认情况下spring上下文环境中有一个针对默认数据源的事务管理器bean.name=transactionManager
但如果有多个数据源,也会有多个事务管理器,这时就不确定需要用哪个事务管理器了,所以就抛出NoUniqueBeanDefinitionException异常了,可以指定一下。@Transactional(value = "transactionManager")
但多数据源时经常在方法内部切换数据源,所以在方法执行前是无法确定事务管理器的。
2.执行方法
3.方法执行完成后,如果遇到指定异常,用刚才的事务管理器回滚事务,否则提交事务。

最近更新 搜索 提交