Как настроить соединитель ActiveMQ JCA в JBoss для использования соединений XA?

В JBoss 5.1.0 у меня есть источник данных (PostgreSQL 8.3.11), настроенный с использованием *-ds.xml (стандартный jboss DS). Он использует XADataSource (PGXADataSource). У меня также есть брокер ActiveMQ (сейчас он работает как в виртуальной машине под JBoss, но последний будет на отдельном сервере).

Что я хочу сделать, так это заставить фабрику соединений ActiveMQ и источник данных участвовать в транзакциях XA. Например, я хочу обновить запись БД и отправить сообщение JMS как UOW. Вы поняли идею.

Я настроил PGXADataSource в файле my-pg-ds.xml, и он работает (я могу отслеживать выполнение до метод запуска PGXAConnection). Я попытался настроить ActiveMQXAConnectionFactory. непосредственно в Spring (я использую Spring 3.0.2.RELEASE), но это не работает, потому что в этом случае менеджер транзакций Spring (я использую аннотацию, чтобы позволить Spring настроить JtaTransactionManager, который просто делегирует всю работу диспетчеру транзакций Jboss) не зачисляет XAResource для данного ActiveMQXAConnection. Всякий раз, когда я пытаюсь отправить сообщение, я получаю исключение JMSException, говорящее: «XAResource сеанса не был включен в распределенную транзакцию». выброшено из ActiveMQXASession.

Поскольку это не сработало, я переключился на конфигурацию JCA ActiveMQ ConnectionFactory (на основе этот документ), и он работает для обычных ConnectionFactory, но я не понимаю, как настроить его для использования XAConnectionFactory. Похоже, что адаптер ресурсов просто не имеет надлежащего ManagedConnectionFactory , ManagedConnection и т. д. реализации для фабрики соединений XA.

Я что-то упустил или у меня нет другого выбора, кроме как написать XA-оболочки для адаптера ресурсов?


person Georgy Bolyuba    schedule 02.07.2010    source источник


Ответы (1)


Хорошо, я нашел решение. Jboss включает коннектор JCA для любой фабрики JMS (поддерживает оба типа транзакций: 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 и привязать его к java:/activemq/XAConnectionFactory. Есть несколько способов сделать это (например, внедрить оболочку MBean).

Поскольку я Jboss 5, я использовал микроконтейнер (который, вероятно, будет работать в Jboss 6). Я добавил файл activemq-jms-jboss-beans.xml в deployersdirectory:

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

Я создаю bean-компонент ActiveMQXAConnectionFactory. Чтобы привязать его к JNDI, я добавляю к нему аннотацию JndiBinding. Чтобы эта аннотация работала, нам нужен JndiLifecycleCallback. Насколько я могу судить, JndiLifecycleCallback вызывается для каждого bean-компонента, созданного микроконтейнером, и проверяет наличие аннотации JndiBinding для этого bean-компонента.

person Georgy Bolyuba    schedule 06.07.2010
comment
Где мне нужно установить имя пользователя и пароль? это атрибут или свойство? как это называется (начинайте с заглавных букв или с маленькой буквы) - person Arvind; 03.04.2018