在 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/