Транзакция Apache Camel: транзакционные сеансы не поддерживаются прямым транспортом

#transactions #apache-camel #solace

#транзакции #apache-camel #утешение

Вопрос:

Я использую Camel для загрузки сообщений из очереди утешения и с трудом понимаю управление транзакциями.

Поток выглядит следующим образом: сообщение загружается из очереди утешения и затем помещается в одну из многих очередей утешения (называемых промежуточными) в зависимости от некоторой логики. Из этих промежуточных очередей сообщение направляется на процессор (bean) с использованием компонента SEDA и, наконец, отправляется в другую очередь утешения.

Я настроил транзакцию как

 <bean id="propagationReqd" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
        <property name="transactionManager" ref="jmsTransactionManager" />
        <property name="propagationBehaviorName" value="PROPAGATION_REQUIRED" />
</bean>
  

Сообщение сохраняется в .solace.очередь, если исключение вызвано sequencer, но оно теряется, если сообщение было передано из промежуточной очереди в SEDA в компонент msgProcessor и выдается следующее исключение.

Не удалось создать транзакцию JMS; вложенным исключением является исключение com.solacesystems.jms.ConfigurationException: транзакционные сеансы или сеансы XA не поддерживаются прямым транспортом

Насколько я понимаю, это происходит потому, что SEDA не является физической очередью, поэтому сообщение теряется при возникновении исключения, но я думал, что промежуточная очередь утешения сохранит его.

Конфигурация маршрутизации:

 <camel:route id="msg.router">
    <camel:from uri="{{in.solace.queue}}" />
    <camel:transacted ref="propagationReqd" />
    <camel:to uri="direct:msgSequencer" />
</camel:route>

<camel:route id="msg.processor">
    <camel:from uri="direct:msgSequencer" />
    <camel:transacted ref="propagationReqd" />
    <camel:process ref="sequencer" />
    <camel:choice>
        <camel:when>
            <camel:simple>${headers.MsgId} == '0'</camel:simple>
            <camel:to uri="{{stage.solace.queue.0}}" />
        </camel:when>
        <camel:when>
            <camel:simple>${headers.MsgId} == '1'</camel:simple>
            <camel:to uri="{{stage.solace.queue.1}}" />
        </camel:when>
        ...
        ...
        ...
    </camel:choice>
</camel:route>

<camel:route id="msg.seda.0">
    <camel:from uri="{{stage.solace.queue.0}}" />
    <camel:transacted ref="propagationReqd" />
    <camel:to uri="seda:processor.0" />
</camel:route>

<camel:route id="msg.seda.1">
    <camel:from uri="{{stage.solace.queue.1}}" />
    <camel:transacted ref="propagationReqd" />
    <camel:to uri="seda:processor.1" />
</camel:route> 

<camel:route id="msg.process.0">
    <camel:from uri="seda:processor.0?concurrentConsumers=4amp;amp;waitForTaskToComplete=Neveramp;amp;purgeWhenStopping=true" />
    <camel:transacted ref="propagationReqd" />
    <camel:process ref="msgProcessor" />
    <camel:to uri="{{final.queue}}" />
</camel:route>

<camel:route id="msg.process.1">
    <camel:from uri="seda:processor.1?concurrentConsumers=4amp;amp;waitForTaskToComplete=Neveramp;amp;purgeWhenStopping=true" />
    <camel:transacted ref="propagationReqd" />
    <camel:process ref="msgProcessor" />
    <camel:to uri="{{final.queue}}" />
</camel:route>
  

Признателен, если кто-нибудь может указать, что я делаю не так?

Заранее спасибо.

Ответ №1:

  1. Ошибка звучит как проблема конфигурации с настройкой фабрики соединений Solace.

  2. К вашему сведению: конечные точки seda не могут учитываться в транзакции, если они асинхронны.

  3. Если вам действительно нужны транзакции без всех шагов, я бы поместил сообщение обратно в другую очередь solace вместо конечной точки seda

Комментарии:

1. Мэтт, я должен использовать SEDA из-за определенного SLA для обработки сообщений, но подумаю о введении другой очереди утешения для передачи сообщений.

Ответ №2:

Не удалось создать транзакцию JMS; вложенным исключением является исключение com.solacesystems.jms.ConfigurationException: транзакционные сеансы или сеансы XA не поддерживаются прямым транспортом

Solace не разрешает транзакции, которые используют фабрики соединений JMS с включенным прямым транспортом. Это является причиной вашего исключения.

Решение здесь состоит в том, чтобы отключить прямой транспорт на фабрике соединений, используемой вашим msgProcessor компонентом, чтобы позволить транзакциям избавиться от этого исключения.

Сообщение сохраняется в .solace.очередь, если исключение вызывается секвенсором, но оно теряется, если сообщение было передано из промежуточной очереди в SEDA в компонент msgProcessor и выдается следующее исключение.

Из http://camel.apache.org/seda.html , похоже, что SEDA не поддерживает восстановление / транзакции.

Этот компонент не реализует какой-либо вид сохранения или восстановления, если виртуальная машина завершает работу, пока сообщения еще не обработаны. Если вам нужна постоянство, надежность или распределенный SEDA, попробуйте использовать JMS или ActiveMQ.

Комментарии:

1. но сообщение не будет сохранено в случае завершения работы виртуальной машины, а не в случае, если приложение выдает какое-либо исключение.