2010-07-02 44 views
7

在JBoss 5.1.0上,我使用* -ds.xml(标准jboss DS)配置了Datasource(PostgreSQL 8.3.11)。它使用XADataSource(PGXADataSource)。我也有ActiveMQ代理(现在它在JBoss下运行在虚拟机中,但它将在单独的服务器上运行)。如何在JBoss中配置ActiveMQ JCA连接器以使用XA连接?

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

我在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连接工厂的JCA配置(基于this文件)和它的作品定期,但我不明白我怎么可以配置为使用XAConnectionFactory。看起来好像Resource Adapter根本没有用于XA连接工厂的适当的ManagedConnectionFactory,ManagedConnection等实现。

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

回答

6

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

首先,activemq-jms-ds.xml文件进入deploy目录旁边的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,JmsProviderAdapter用于存储连接工厂的JNDI名称(在我的配置中,所有名称都相同)。

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

由于我是Jboss 5,我使用了microcontainer(这很可能在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豆。为了将它绑定到JNDI,我使用JndiBinding注释对它进行了注释。为了使这个注解起作用,我们需要JndiLifecycleCallback。据我所知,每个由microcontainer创建的bean都会调用JndiLifecycleCallback,并检查该bean上的JndiBinding注释。