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

时间:2010-07-02 17:40:44

标签: java java-ee jboss activemq

在JBoss 5.1.0上,我使用* -ds.xml(标准jboss DS)配置了Datasource(PostgreSQL 8.3.11)。它使用XADataSource(PGXADataSource)。我也有ActiveMQ代理(现在它在VM中运行,在JBoss下,但它将在不同的服务器上运行)。

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

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

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

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

1 个答案:

答案 0 :(得分:7)

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

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

<?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文件添加到deployers direcotry:

<?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。据我所知,JidiLifecycleCallback在由微容器创建的每个bean上调用,并检查该bean上的JndiBinding注释。