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

Posted

技术标签:

【中文标题】如何在 JBoss 中配置 ActiveMQ JCA 连接器以使用 XA 连接?【英文标题】:How to configure ActiveMQ JCA connector in JBoss to use XA connections? 【发布时间】:2011-03-11 05:18:43 【问题描述】:

在 JBoss 5.1.0 上,我使用 *-ds.xml(标准 jboss DS)配置了数据源(PostgreSQL 8.3.11)。它使用 XADataSource (PGXADataSource)。我也有 ActiveMQ 代理(现在它在 JBoss 下作为虚拟机内运行,但稍后它将在单独的服务器上)。

我想做的是让 ActiveMQ 连接工厂和数据源参与 XA 事务。例如,我想更新 DB 记录并将 JMS 消息作为 UOW 发送。你明白了。

我在 my-pg-ds.xml 中配置了 PGXADataSource 并且它可以工作(我可以一直跟踪执行到PGXAConnection's start method)。我曾尝试直接在 Spring 中配置 ActiveMQXAConnectionFactory(我使用的是 Spring 3.0.2.RELEASE),但这不起作用,因为在这种情况下 Spring 事务管理器(我使用注释让 Spring 配置 JtaTransactionManager,它只是委托Jboss 事务管理器的所有工作)没有为给定的ActiveMQXAConnection 征集 XAResource。每当我尝试发送消息时,我都会收到异常 JMSException,提示“会话的 XAResource 尚未加入分布式事务”。从ActiveMQXASession 抛出。

由于这不起作用,我已切换到 ActiveMQ ConnectionFactory 的 JCA 配置(基于 this 文档),它适用于常规 ConnectionFactory,但我不明白如何将其配置为使用 XAConnectionFactory。似乎Resource Adapter 根本没有适当的 ManagedConnectionFactory、ManagedConnection 等 XA 连接工厂的实现。

是我遗漏了什么还是别无选择,只能为资源适配器编写 XA 包装器?

【问题讨论】:

【参考方案1】:

好的,我找到了解决方案。 Jboss 包括适用于任何 JMS 工厂的 JCA 连接器(支持两种类型的事务:XA 和本地)。它位于 /server//deploy/jms-ra.rar。这是我的配置方式。

首先,activemq-jms-ds.xml 文件进入 jms-ra.rar 旁边的部署目录:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE connection-factories
    PUBLIC "-//JBoss//DTD JBOSS JCA Config 1.5//EN"
    "http://www.jboss.org/j2ee/dtd/jboss-ds_1_5.dtd">

<connection-factories>
    <mbean code="org.jboss.jms.jndi.JMSProviderLoader"
       name="jboss.messaging:service=JMSProviderLoader,name=ActiveMQJMSProvider">
        <attribute name="ProviderName">ActiveMQJMSProvider</attribute>
        <attribute name="ProviderAdapterClass">org.jboss.jms.jndi.JNDIProviderAdapter</attribute>
        <attribute name="FactoryRef">java:/activemq/XAConnectionFactory</attribute>
        <attribute name="QueueFactoryRef">java:/activemq/XAConnectionFactory</attribute>
        <attribute name="TopicFactoryRef">java:/activemq/XAConnectionFactory</attribute>
    </mbean>

    <tx-connection-factory>
        <jndi-name>JmsXAConnectionFactory</jndi-name>
        <xa-transaction/>
        <rar-name>jms-ra.rar</rar-name>
        <connection-definition>org.jboss.resource.adapter.jms.JmsConnectionFactory</connection-definition>
        <config-property name="JmsProviderAdapterJNDI" type="java.lang.String">java:/ActiveMQJMSProvider</config-property>
    </tx-connection-factory>
</connection-factories>

这告诉 Jboss 查看 jms-ra.rar 并找到可以为org.jboss.resource.adapter.jms.JmsConnectionFactory 提供托管连接工厂的适配器。 jms 适配器内部依赖于 JmsProviderAdapter,它用于存储连接工厂的 JNDI 名称(在我的配置中,所有名称都相同)。

我使用 mbean 标记来配置 JMSProviderLoader(这是从内部 JBoss 配置之一复制的)。现在,我所要做的就是以某种方式创建我的 XA 连接工厂的实例并将其绑定到java:/activemq/XAConnectionFactory。有几种方法可以做到这一点(例如,实现 MBean 包装器)。

因为我是 Jboss 5,所以我使用了微容器(很可能在 Jboss 6 中工作)。我将activemq-jms-jboss-beans.xml 文件添加到deployersdirecotry:

<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="urn:jboss:bean-deployer:2.0">
    <!-- Define a Jndi binding aspect/annotation that exposes beans via jndi
        when they are registered with the kernel.
    -->
    <aop:lifecycle-configure xmlns:aop="urn:jboss:aop-beans:1.0"
        name="DependencyAdvice"
        class="org.jboss.aop.microcontainer.aspects.jndi.JndiLifecycleCallback"
        classes="@org.jboss.aop.microcontainer.aspects.jndi.JndiBinding"
        manager-bean="AspectManager"
        manager-property="aspectManager">
    </aop:lifecycle-configure>

    <bean name="ActiveMQXAConnectionFactory" class="org.apache.activemq.ActiveMQXAConnectionFactory">
        <annotation>@org.jboss.aop.microcontainer.aspects.jndi.JndiBinding(name="activemq/XAConnectionFactory", aliases="java:/activemq/XAConnectionFactory")</annotation>
        <property name="brokerURL">vm://localhost</property>
    </bean>
</deployment>

我创建了一个ActiveMQXAConnectionFactory bean。为了将它绑定到 JNDI,我使用 JndiBinding 注释对其进行了注释。为了使这个注解起作用,我们需要 JndiLifecycleCallback。据我所知,在微容器创建的每个 bean 上都会调用 JndiLifecycleCallback 并检查该 bean 上的 JndiBinding 注释。

【讨论】:

需要在哪里设置用户名和密码?是属性还是属性?那是什么名字(以大写或小写开头)

以上是关于如何在 JBoss 中配置 ActiveMQ JCA 连接器以使用 XA 连接?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 ActiveMQ Artemis 在 Wildfly 24 服务上配置 jms-queue

JBoss 和 ActiveMQ 之间挂起的 Socket.read() 线程

将jml的子记录拆分为jboss fuse中activeMQ中的各个消息

javax.jms.JMSException:在向JBoss EAP 7.2中的嵌入式ActiveMQ Artemis发送消息时,未能创建会话工厂。

如何在 jboss 7 中配置两个 https 连接器端口?

如何使用 HikariCP 在 Jboss 中配置 JNDI 数据源?