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

Geo*_*uba 8 java jboss activemq-classic java-ee

在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的start方法).我曾尝试直接在Spring中配置ActiveMQXAConnectionFactory(我使用的是Spring 3.0.2.RELEASE),但这不起作用,因为在这种情况下是Spring事务管理器(我使用注释让Spring配置JtaTransactionManager,它只需将所有工作委托给Jboss事务管理器)没有为给定的ActiveMQXAConnection登记XAResource .每当我尝试发送消息时,我都会收到异常JMSException,说"会话的XAResource尚未在分布式事务中登记".从ActiveMQXASession抛出.

由于这不起作用,我已切换到ActiveMQ ConnectionFactory的JCA配置(基于文档),它适用于常规ConnectionFactory,但我不明白如何配置它以使用XAConnectionFactory.看起来资源适配器根本没有适用于XA连接工厂的ManagedConnectionFactory,ManagedConnection等实现.

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

Geo*_*uba 7

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

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

<?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>
Run Code Online (Sandbox Code Playgroud)

这告诉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>
Run Code Online (Sandbox Code Playgroud)

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