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

标签 java jakarta-ee jboss activemq

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

我想做的是让 ActiveMQ Connection Factory 和 Datasource 参与 XA Transactions。例如,我想更新 DB 记录并将 JMS 消息作为 UOW 发送。你明白了。

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

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

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

最佳答案

好的,我找到了解决方案。 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 连接工厂的实例并将其绑定(bind)到 java:/activemq/XAConnectionFactory。有几种方法可以做到这一点(例如,实现 MBean 包装器)。

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

<?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。为了将它绑定(bind)到 JNDI,我用 JndiBinding 注释对其进行了注释。为了让这个注解起作用,我们需要 JndiLifecycleCallback。据我所知,微容器创建的每个 bean 都会调用 JndiLifecycleCallback 并检查该 bean 上的 JndiBinding 注释。

关于java - 如何在 JBoss 中配置 ActiveMQ JCA 连接器以使用 XA 连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3167905/

相关文章:

java - 无法从@OneToMany 集合中删除元素

Hibernate SQLQuery 绕过 Hibernate session 缓存

java - RestEasy简单配置中的ClassNotFoundException

Java ExecutorService 解决递归斐波那契数列

java - MessageDigest.getInstance ("SHA") 返回什么特定的哈希算法?

Java,获取核心转储

java - 在 TomEE 中注入(inject) EntityManager 会导致 NullPointerException?

java - JSTL核心fmt :message Tag Dynamic message using bundle/properties file

java - 如何进行正确的 HQL 连接

java - 服务器发送事件 (SSE) 集群连接处理