Java 如何在Spring中配置ActiveMQ和H2数据库以使用XA连接?(比特龙)

Java 如何在Spring中配置ActiveMQ和H2数据库以使用XA连接?(比特龙),java,spring,spring-boot,spring-jms,jta,Java,Spring,Spring Boot,Spring Jms,Jta,应用程序引发异常:由以下原因引起:javax.jms.JMSException:会话的XAResource未在分布式事务中登记 如何修复它 import bitronix.tm.BitronixTransactionManager; import bitronix.tm.TransactionManagerServices; import bitronix.tm.resource.jms.PoolingConnectionFactory; import org.springframework.

应用程序引发异常:由以下原因引起:javax.jms.JMSException:会话的XAResource未在分布式事务中登记

如何修复它

 import bitronix.tm.BitronixTransactionManager;
import bitronix.tm.TransactionManagerServices;
import bitronix.tm.resource.jms.PoolingConnectionFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.jta.JtaTransactionManager;

import javax.jms.ConnectionFactory;
import javax.transaction.TransactionManager;
@Configuration
@EnableTransactionManagement
public class BitronixConfig {

    @Value("${spring.activemq.broker-url}")
    private String brokerUrl;

    @Bean(name = "bitronixCfg")
    public bitronix.tm.Configuration configuredBitronix() {
        bitronix.tm.Configuration conf
                = TransactionManagerServices.getConfiguration();
        conf.setServerId("TanderTask");
        conf.setLogPart1Filename("./tx-logs/part1.btm");
        conf.setLogPart2Filename("./tx-logs/part2.btm");

        return conf;
    }

    @Bean(name = "bitronixTransactionManager", destroyMethod="shutdown")
    //@DependsOn("bitronixCfg")
    public BitronixTransactionManager bitronixTransactionManager() throws Throwable {
        BitronixTransactionManager bitronixTransactionManager = TransactionManagerServices.getTransactionManager();
        //bitronixTransactionManager.setTransactionTimeout(10000);

        return bitronixTransactionManager;
    }

    @Bean(name = "transactionManager")
    //@DependsOn("bitronixTransactionManager")
    public PlatformTransactionManager transactionManager(TransactionManager bitronixTransactionManager) throws Throwable {
        return new JtaTransactionManager(bitronixTransactionManager);
    }

    @Bean("xaJmsConnectionFactory")
    //@DependsOn("bitronixTransactionManager")
    public ConnectionFactory connectionFactoryLocal() {
        PoolingConnectionFactory btmPoolingConnectionFactory = new PoolingConnectionFactory();
        btmPoolingConnectionFactory.setClassName("org.apache.activemq.ActiveMQXAConnectionFactory");
        btmPoolingConnectionFactory.setUniqueName("AMQLocal");
        btmPoolingConnectionFactory.setMinPoolSize(1);
        btmPoolingConnectionFactory.setMaxPoolSize(5);
        btmPoolingConnectionFactory.setAllowLocalTransactions(true);
        btmPoolingConnectionFactory.getDriverProperties().setProperty("brokerURL", brokerUrl);
        btmPoolingConnectionFactory.init();

        return btmPoolingConnectionFactory;
    }





import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Transactional;

import javax.jms.BytesMessage;


@Service
public class JmsFileListener {
    private static Logger logger = LoggerFactory.getLogger(JmsListener.class);

    @Transactional
    @JmsListener(destination = "${spring.activemq.destination}")
    public void receiveXmlFile(BytesMessage bytesMessage) {
        try {
            byte[] bytes = new byte[(int) bytesMessage.getBodyLength()];
            bytesMessage.readBytes(bytes);
            String out = new String(bytes);
            logger.info(
                    String.format(" Queue = %s; File contains = %s",
                            "${spring.activemq.destination}", out)
            );
        } catch (Exception e) {
            logger.error("Error in JmsFileListener class!!", e);
        }
    }
}
路线.等级

import com.almod.springjta.db.H2Repo;
import org.apache.camel.builder.RouteBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Route extends RouteBuilder {
    @Override
    public void configure() throws Exception {
        from("file:data?noop=true")
                .to("jms:example");
                /*.choice()
                    .when(header("CamelFileName").endsWith(".xml"))
                        .to("jms:example")

                    .when(header("CamelFileName").endsWith(".txt"))
                        .bean(H2Repo.class, "writeInDB")
                        .to("jms:example")

                    .otherwise()
                        .throwException(new Exception(" Wrong extension !"))
                        .to("jms:invalid-queue")
                .end();*/
    }
}
应用程序属性

# ActiveMQ
spring.activemq.broker-url=vm://embedded-broker
spring.activemq.destination=example
spring.jms.template.default-destination=example

# H2 Database
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.datasource.schema=db/schema.sql
pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.almod</groupId>
    <artifactId>springjta</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>SpringJTA</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <apache-camel-version>2.22.1</apache-camel-version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-activemq</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-kahadb-store</artifactId>
            <version>5.15.4</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jta-bitronix</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-spring-boot-starter</artifactId>
            <version>${apache-camel-version}</version> <!-- use the same version as your Camel core version -->
        </dependency>

        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-core</artifactId>
            <version>${apache-camel-version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-spring</artifactId>
            <version>${apache-camel-version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-stream</artifactId>
            <version>${apache-camel-version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-spring-javaconfig</artifactId>
            <version>${apache-camel-version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.camel/camel-jms -->
        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-jms</artifactId>
            <version>${apache-camel-version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.camel/camel-context -->
        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-context</artifactId>
            <version>${apache-camel-version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.camel</groupId>
            <artifactId>camel-mail</artifactId>
            <version>${apache-camel-version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
org.springframework.jms.UncategorizedJmsException: Uncategorized exception occurred during JMS processing; nested exception is javax.jms.JMSException: Session's XAResource has not been enlisted in a distributed transaction.
    at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:311) ~[spring-jms-5.3.1.jar:5.3.1]
    at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:185) ~[spring-jms-5.3.1.jar:5.3.1]
    at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:507) ~[spring-jms-5.3.1.jar:5.3.1]
    at org.apache.camel.component.jms.JmsConfiguration$CamelJmsTemplate.send(JmsConfiguration.java:526) ~[camel-jms-2.22.1.jar:2.22.1]
    at org.apache.camel.component.jms.JmsProducer.doSend(JmsProducer.java:440) ~[camel-jms-2.22.1.jar:2.22.1]
    at org.apache.camel.component.jms.JmsProducer.processInOnly(JmsProducer.java:394) ~[camel-jms-2.22.1.jar:2.22.1]
    at org.apache.camel.component.jms.JmsProducer.process(JmsProducer.java:157) ~[camel-jms-2.22.1.jar:2.22.1]
    at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:148) ~[camel-core-2.22.1.jar:2.22.1]
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:548) ~[camel-core-2.22.1.jar:2.22.1]
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201) [camel-core-2.22.1.jar:2.22.1]
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201) [camel-core-2.22.1.jar:2.22.1]
    at org.apache.camel.component.file.GenericFileConsumer.processExchange(GenericFileConsumer.java:454) [camel-core-2.22.1.jar:2.22.1]
    at org.apache.camel.component.file.GenericFileConsumer.processBatch(GenericFileConsumer.java:223) [camel-core-2.22.1.jar:2.22.1]
    at org.apache.camel.component.file.GenericFileConsumer.poll(GenericFileConsumer.java:187) [camel-core-2.22.1.jar:2.22.1]
    at org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:174) [camel-core-2.22.1.jar:2.22.1]
    at org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.java:101) [camel-core-2.22.1.jar:2.22.1]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_241]
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [na:1.8.0_241]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_241]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [na:1.8.0_241]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_241]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_241]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_241]
Caused by: javax.jms.JMSException: Session's XAResource has not been enlisted in a distributed transaction.
    at org.apache.activemq.ActiveMQXASession.doStartTransaction(ActiveMQXASession.java:101) ~[activemq-client-5.16.0.jar:5.16.0]
    at org.apache.activemq.ActiveMQSession.send(ActiveMQSession.java:1919) ~[activemq-client-5.16.0.jar:5.16.0]
    at org.apache.activemq.ActiveMQMessageProducer.send(ActiveMQMessageProducer.java:288) ~[activemq-client-5.16.0.jar:5.16.0]
    at org.apache.activemq.ActiveMQMessageProducer.send(ActiveMQMessageProducer.java:223) ~[activemq-client-5.16.0.jar:5.16.0]
    at org.apache.activemq.ActiveMQMessageProducerSupport.send(ActiveMQMessageProducerSupport.java:241) ~[activemq-client-5.16.0.jar:5.16.0]
    at bitronix.tm.resource.jms.MessageProducerWrapper.send(MessageProducerWrapper.java:79) ~[btm-2.1.4.jar:2.1.4]
    at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:634) ~[spring-jms-5.3.1.jar:5.3.1]
    at org.apache.camel.component.jms.JmsConfiguration$CamelJmsTemplate.doSend(JmsConfiguration.java:634) ~[camel-jms-2.22.1.jar:2.22.1]
    at org.apache.camel.component.jms.JmsConfiguration$CamelJmsTemplate.doSendToDestination(JmsConfiguration.java:573) ~[camel-jms-2.22.1.jar:2.22.1]
    at org.apache.camel.component.jms.JmsConfiguration$CamelJmsTemplate.access$100(JmsConfiguration.java:515) ~[camel-jms-2.22.1.jar:2.22.1]
    at org.apache.camel.component.jms.JmsConfiguration$CamelJmsTemplate$1.doInJms(JmsConfiguration.java:529) ~[camel-jms-2.22.1.jar:2.22.1]
    at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:504) ~[spring-jms-5.3.1.jar:5.3.1]
    ... 20 common frames omitted