Java 多个事务管理器NoniqueBeandDefinitionException

Java 多个事务管理器NoniqueBeandDefinitionException,java,spring,spring-boot,spring-jms,Java,Spring,Spring Boot,Spring Jms,我正在使用Spring引导,我定义了Spring.datasource.*属性来启用我的数据源。如果我只用这个,它就可以了。但是,我现在也尝试使用以下配置将JMS添加到我的应用程序中: @Configuration @EnableJms public class TriggerQueueConfig { private Logger logger = LoggerFactory.getLogger(getClass()); @Value("${jms.host:localhost

我正在使用Spring引导,我定义了
Spring.datasource.*
属性来启用我的数据源。如果我只用这个,它就可以了。但是,我现在也尝试使用以下配置将JMS添加到我的应用程序中:

@Configuration
@EnableJms
public class TriggerQueueConfig {
    private Logger logger = LoggerFactory.getLogger(getClass());
    @Value("${jms.host:localhost}")
    private String host;
    @Value("${jms.port:1414}")
    private int port;
    @Value("${jms.concurrency.min:3}-${jms.concurrency.max:10}")
    private String concurrency;
    @Value("${jms.manager}")
    private String queueManager;
    @Value("${jms.cache:100}")
    private int cacheSize;

    @Bean
    public JmsListenerContainerFactory<?> jmsListenerContainerFactory() throws JMSException {
        logger.debug("Setting queue concurrency to {} (min-max)", concurrency);
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        factory.setConnectionFactory(cachedConnectionFactory());
        factory.setMessageConverter(messageConverter());
        factory.setTransactionManager(transactionManager());
        factory.setSessionTransacted(true);
        factory.setConcurrency(concurrency);
        return factory;
    }

    @Bean(name = "jmsTransactionManager")
    public JmsTransactionManager transactionManager() throws JMSException {
        JmsTransactionManager transactionManager = new JmsTransactionManager();
        transactionManager.setConnectionFactory(cachedConnectionFactory());
        return transactionManager;
    }

    @Bean
    @Primary
    public ConnectionFactory cachedConnectionFactory() throws JMSException {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory(ibmConnectionFactory());
        connectionFactory.setSessionCacheSize(cacheSize);
        connectionFactory.setCacheConsumers(true);
        return connectionFactory;
    }

    @Bean
    public ConnectionFactory ibmConnectionFactory() throws JMSException {
        logger.debug("Connecting to queue on {}:{}", host, port);
        MQQueueConnectionFactory connectionFactory = new MQQueueConnectionFactory();
        connectionFactory.setHostName(host);
        connectionFactory.setPort(port);
        connectionFactory.setQueueManager(queueManager);
        connectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
        return connectionFactory;
    }

    @Bean
    public MessageConverter messageConverter() {
        MarshallingMessageConverter converter = new MarshallingMessageConverter();
        converter.setMarshaller(marshaller());
        converter.setUnmarshaller(marshaller());
        return converter;
    }

    @Bean
    public Jaxb2Marshaller marshaller() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setPackagesToScan("com.example");
        return marshaller;
    }
}
这很有意义,因为两个TransactionManager都是
平台TransactionManager
。通常,您会将
@Primary
放在默认bean的顶部。但是,在本例中,我使用的是Spring boot的自动配置,因此无法在其上添加
@Primary

另一种解决方案是为每个
@Transactional
注释提供事务管理器的名称(例如
@Transactional(“transactionManager”)
,但这将是一项艰巨的工作,拥有一个默认的transactionmanager更有意义,因为JMS transactionmanager是一个例外情况


有没有一种简单的方法来定义默认使用的自动配置的transactionmanager?

Spring boot的“魔力”实际上只是:

@Bean
@ConditionalOnMissingBean(PlatformTransactionManager.class)
public PlatformTransactionManager transactionManager() {
    return new JpaTransactionManager();
}
org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration
类中

请注意
@ConditionalOnMissingBean
注释-仅当
PlatformTransactionManager
类型的bean不存在时,才会配置此注释。因此,您可以通过使用
@Primary
注释创建自己的bean来覆盖此注释:

@Bean
@Primary
public PlatformTransactionManager transactionManager() {
    return new JpaTransactionManager();
}

你能在bean autowired实例上使用@Qualifier注释来说明你要注入哪个transactionManager吗?@DanielHigueras具体在哪里?我正在使用Spring boot魔法,所以我没有创建任何bean。要使用transactionManager,我所要做的就是添加
@Transactional
注释。嗯,也许可以将它作为一个值添加到@Transactional注释?(例如@Transactional(value=“jmsTransactionManager”)
@Bean
@Primary
public PlatformTransactionManager transactionManager() {
    return new JpaTransactionManager();
}