2010-07-02 5 views
7

Auf JBoss 5.1.0 habe ich Datasource (PostgreSQL 8.3.11) konfiguriert mit * -ds.xml (Standard jboss DS). Es verwendet XADataSource (PGXADataSource). Ich habe auch ActiveMQ-Broker (derzeit läuft es als in-VM, unter JBoss, aber es wird auf separaten Server letzteren sein).Konfigurieren des ActiveMQ JCA-Connectors in JBoss für die Verwendung von XA-Verbindungen?

Ich möchte ActiveMQ Connection Factory und Datasource zur Teilnahme an XA-Transaktionen machen. Zum Beispiel möchte ich den DB-Eintrag aktualisieren und eine JMS-Nachricht als UOW senden. Du hast die Idee.

Ich habe PGXADataSource in my-pg-ds.xml konfiguriert und es funktioniert (ich kann die Ausführung bis zu PGXAConnection's start method verfolgen). Ich habe versucht, ActiveMQXAConnectionFactory direkt im Frühling zu konfigurieren (ich benutze Spring 3.0.2.RELEASE), aber das funktioniert nicht, weil in diesem Fall Spring transaction manager (Ich verwende Annotation, um Spring konfigurieren JtaTransactionManager, die einfach alle Arbeit an delegiert Jboss transaction manager) führt XAResource für gegebene ActiveMQXAConnection nicht ein. Immer wenn ich versuche, eine Nachricht zu senden, erhalte ich eine Ausnahme JMSException, die besagt, dass die XAResource der Sitzung nicht in einer verteilten Transaktion eingetragen wurde. geworfen von ActiveMQXASession. Da

dass, funktionierte nicht ich JCA Konfiguration von ActiveMQ ConnectionFactory- (basierend auf this Dokument) eingeschaltet haben und es funktioniert für regelmäßige , aber ich verstehe nicht, wie kann ich sie konfigurieren XAConnectionFactory verwenden. Es scheint wie Resource Adapter hat einfach nicht ordnungsgemäße ManagedConnectionFactory, ManagedConnection usw. Implementierungen für XA Connection Factory.

Fehle ich etwas oder habe ich keine andere Wahl, als XA-Wrapper für den Ressourcenadapter zu schreiben?

Antwort

6

Ok, ich habe die Lösung gefunden. Jboss enthält den JCA-Connector für jede JMS-Factory (unterstützt beide Arten von Transaktionen: XA und local). Es befindet sich in /server/de/deploy/jms-ra.rar. Hier ist, wie ich es konfiguriert habe.

Zuerst activemq-jms-ds.xml-Datei, die neben jms-ra.rar in deploy-Verzeichnis geht:

<?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> 

Dies sagt Jboss in jms-ra.rar zu suchen und Adapter finden, die Verbindungsfactory für org.jboss.resource.adapter.jms.JmsConnectionFactory verwaltet liefern . Intern hängt Jms-Adapter von JmsProviderAdapter ab, der verwendet wird, um JNDI-Namen von Verbindungsfabriken zu speichern (in meiner Konfiguration sind alle Namen gleich).

Ich benutze mbean Tag JMSProviderLoader zu konfigurieren (dies von einem internen JBoss configs kopiert wird). Jetzt muss ich lediglich eine Instanz meiner XA-Verbindungsfactory erstellen und sie an java:/activemq/XAConnectionFactory binden. Dafür gibt es mehrere Möglichkeiten (z. B. MBean-Wrapper implementieren).

Da ich Jboss 5 I verwendet Mikrocontainer (die in Jboss 6 wahrscheinlich ist, arbeiten). Ich habe activemq-jms-jboss-beans.xml Datei in 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> 

ich eine ActiveMQXAConnectionFactory Bohne. Um es an JNDI zu binden, notiere ich es mit JndiBinding Annotation. Damit diese Anmerkung funktioniert, benötigen wir JniLifecycleCallback. Soweit ich das beurteilen kann, ist JndiLifecycleCallback auf jeder Bohne von Mikrocontainern und prüft, ob JndiBinding Anmerkung an diesem Bean erstellt genannt.