我使用Spring Integration XML配置来轮询一些数据库表,然后进行一些处理。一切都很好,直到我们引入了多个数据源。之后,我们得到间歇性NoUniqueBeanDefinitionException
异常。
问题是我们不知道这个异常来自哪个poller
(我们使用的是基于xml的配置),因为我们有很多轮询器。由于堆栈跟踪显示了AbstractPollingEndpoint.java
,因此我们查看了所有轮询器并验证了transaction-manager
是否正确设置。
代码:
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="transactionManagerSec" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactorySecondary"/>
<property name="dataSource" ref="dataSourceSec" />
</bean>
<jpa:repositories base-package="com.acme.dao" entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="transactionManager" />
<jpa:repositories base-package="com.acme.tmpdao" entity-manager-factory-ref="entityManagerFactorySecondary" transaction-manager-ref="transactionManagerSec" />
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" primary="true" id="entityManagerFactory">
<property name="dataSource" ref="dataSource"/>
<property name="persistenceUnitName" value="${spring.persistence.unitname}" />
<property name="persistenceProvider" ref="eclipsePP" />
</bean>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" primary="false" id="entityManagerFactorySecondary">
<property name="dataSource" ref="dataSourceSec"/>
<property name="persistenceUnitName" value="${spring.secondary.persistence.unitname}" />
<property name="persistenceProvider" ref="eclipsePPSec" />
</bean>
<bean class="org.eclipse.persistence.jpa.PersistenceProvider" id="eclipsePP" />
<bean class="org.eclipse.persistence.jpa.PersistenceProvider" id="eclipsePPSec" />
<int:transaction-synchronization-factory id="txSyncFactory">
<int:before-commit channel="updateEntityChannel" />
</int:transaction-synchronization-factory>
<int-jpa:inbound-channel-adapter id="procStateAdapter" channel="inProcStateChannel"
entity-manager="entityManagerFactory"
auto-startup="true"
jpa-query="select <SqlQuery> order by en.lastUpdatedTime"
max-results="10"
>
<int:poller max-messages-per-poll="10" fixed-rate="10" >
<int:transactional propagation="REQUIRES_NEW" transaction-manager="transactionManager" synchronization-factory="txSyncFactory"/>
</int:poller>
</int-jpa:inbound-channel-adapter>
2019-10-13 07:51:16,625 [task-scheduler-5] ERROR o.s.i.h.LoggingHandler:handleMessageInternal:192 - org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.transaction.PlatformTransactionManager] is defined: expected single matching bean but found 2: transactionManager,transactionManagerSec
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:368)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:334)
at org.springframework.transaction.interceptor.TransactionAspectSupport.determineTransactionManager(TransactionAspectSupport.java:366)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:270)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy409.toString(Unknown Source)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at org.springframework.integration.endpoint.PollingConsumer.handleMessage(PollingConsumer.java:141)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.doPoll(AbstractPollingEndpoint.java:272)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.access$000(AbstractPollingEndpoint.java:58)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$1.call(AbstractPollingEndpoint.java:190)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$1.call(AbstractPollingEndpoint.java:186)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller$1.run(AbstractPollingEndpoint.java:353)
at org.springframework.integration.util.ErrorHandlingTaskExecutor$1.run(ErrorHandlingTaskExecutor.java:55)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
at org.springframework.integration.util.ErrorHandlingTaskExecutor.execute(ErrorHandlingTaskExecutor.java:51)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller.run(AbstractPollingEndpoint.java:344)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
有没有办法从下面的堆栈中找出位于AbstractPollingEndpoint$Poller$1.run
开头的轮询器的id
,以便我们进一步调试?
或者我们的多数据源配置中缺少的任何其他内容。
1条答案
按热度按时间nxowjjhe1#
在stacktrace中可以看到:
所以问题是spring找到了两个符合自动装配条件的bean。尝试使用@Shailesh建议的属性将其中一个bean设置为primary:
或者使用限定符将两个事务bean分开,然后指定要在代码中使用哪个事务管理器,如:
当你想使用一个特定的事务管理器时,使用如下注解指定它:
注意:您也可以通过xml来配置
您可以使用@Transactional annotation的value属性来可选地指定要使用的PlatformTransactionManager的标识。这可以是bean名称,也可以是事务管理器bean的限定符值。如果找不到专门限定的PlatformTransactionManager bean,则仍使用默认的目标bean名称transactionManager。
正式文件