使用 spring 和 activemq 的 XA 事务

Posted

技术标签:

【中文标题】使用 spring 和 activemq 的 XA 事务【英文标题】:XA transactions using spring and activemq 【发布时间】:2015-05-26 02:57:21 【问题描述】:

我试图证明我不需要部署到 JBoss EAP 6.3 的 activemq rar 来使用 XA 事务...我只想使用活动的 mq 客户端 jar。我创建了一个简单的 spring-boot 项目并公开了一个通过 restful web 服务公开的方法。如果我部署了 active-mq rar,以下代码会正确回滚。

@Transactional
public void work() throws Exception 

    ConnectionFactory connectionFactory = (ConnectionFactory) this.context
            .getBean("jmsConnectionFactory");

    // Send a message
    MessageCreator messageCreator = new MessageCreator() 
        @Override
        public Message createMessage(Session session) throws JMSException 
            return session.createTextMessage("Test message!");
        
    ;

    JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
    System.out.println("Sending a new message.");
    jmsTemplate.send("test-destination", messageCreator);

    throw new Exception("Something bad happened!!");

但是,当我通过 JNDI 创建自己的 ConnectionFactory 时,代码不会回滚,消息仍然会被发送。

@Transactional
public void work() throws Exception 

    ConnectionFactory connectionFactory = null;
    try 
        Context ctx = new InitialContext();
        connectionFactory = (ConnectionFactory) ctx.lookup("java:/ConnectionFactory");
     catch (NamingException e) 
        e.printStackTrace();
        throw new RuntimeException(e);
    

    // Send a message
    MessageCreator messageCreator = new MessageCreator() 
        @Override
        public Message createMessage(Session session) throws JMSException 
            return session.createTextMessage("Test message!");
        
    ;

    JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
    System.out.println("Sending a new message.");
    jmsTemplate.send("test-destination", messageCreator);

    throw new Exception("Something bad happened!!");

我想了解的是,当 activemq rar 部署为 EAP 上的资源适配器时,spring-boot 在启动时做了什么来提供 XA 支持。如果我明白这一点,我想我应该能够将 active-mq 客户端 jar 和我的数据库 jar 打包到我的 spring 应用程序中(不是基于 spring-boot),并且仍然提供 XA 支持,即让 spring 通过委派来管理 XA 事务到 PlatformTransactionManager。

任何帮助将不胜感激。

谢谢,威尔

【问题讨论】:

哪个 Spring Boot 版本以及您为什么不使用 Spring Boot...如果您手动配置所有内容而不是让 Spring Boot 进行自动配置,那么在我看来。 嗨,我正在使用 spring-boot 1.2.1 来尝试证明这一点。我很想使用弹簧靴。但是,我正在使用一个已有 5 年历史的系统(它使用 spring,iBatis 托管在 weblogic 上)他们正在将应用程序移动到 JBoss EAP 和 JBoss A-MQ。它们需要 XA 事务支持,我想看看是否可以将 A-MQ 客户端 jar 与适当的 XA 数据库驱动程序结合使用。 我想了解使用 spring 的 PlatformManager 在应用服务器存在时如何将其委托给应用服务器。当我使用 spring-boot 时,我可以看到 PlatformManager 和 jmsConnectionFactory bean 正在加载。但是,当我不使用activemq rar并使用客户端时,似乎使用的是ActiveMQConnectionFactory而不是ActiveMQXAConnectionFactory。 【参考方案1】:

Spring Boot 是关于约定的。您需要指出您正在连接到 XA 连接工厂的 Spring Boot。 根据 Spring Boot 文档(32.3 Using a Java EE managed transaction manager):

Spring Boot 将尝试通过在 JNDI 路径 java:/JmsXAjava:/XAConnectionFactory 处查找 ConnectionFactory 来自动配置 JMS

【讨论】:

谢谢达米安。当我自动接线时 谢谢达米安,当自动连接默认连接工厂时,它可以工作。 // 注入主(XA 感知)ConnectionFactory @Autowired private ConnectionFactory defaultConnectionFactory;我 我还必须使用应用服务器 TransactionManager @Bean public PlatformTransactionManager platformTransactionManager() throws Throwable JtaTransactionManager jtaTransactionManager = new JtaTransactionManager(); jtaTransactionManager.setUserTransactionName("java:jboss/UserTransaction"); jtaTransactionManager.setTransactionManagerName("java:/TransactionManager");返回 jtaTransactionManager;

以上是关于使用 spring 和 activemq 的 XA 事务的主要内容,如果未能解决你的问题,请参考以下文章

ActiveMQ JMS XA Atomikos - 事务未启动错误

如何在 JBoss 中配置 ActiveMQ JCA 连接器以使用 XA 连接?

如何在 Mule XA 事务中为 ActiveMQ 启用 RedeliveryDelay

ActiveMQ基本知识

如何实现XA式非XA式Spring分布式事务

学习ActiveMQ:spring与ActiveMQ整合