0

I'm using Camel to download messages from Solace queue and having hard time in understanding the transaction management.

Flow is like this, message is downloaded from a Solace queue and is then pushed to one of many Solace queues (called staging) depending on some logic. From these staging queues message is routed to a processor (bean) using SEDA component and finally it is sent to a another Solace queue.

I've configured transaction as

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

Message is retained on in.solace.queue if exception is raised by sequencer but it is lost if message has been passed from staging queue to SEDA to msgProcessor bean and following exception is thrown.

Could not create JMS transaction; nested exception is com.solacesystems.jms.ConfigurationException: Transacted sessions or XA sessions are not supported with direct transport

My understanding is it is happening because SEDA is not a physical queue hence message is lost when exception is thrown but I thought staging Solace queue will retain it.

Routing config:

<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=4&amp;waitForTaskToComplete=Never&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=4&amp;waitForTaskToComplete=Never&amp;purgeWhenStopping=true" />
    <camel:transacted ref="propagationReqd" />
    <camel:process ref="msgProcessor" />
    <camel:to uri="{{final.queue}}" />
</camel:route>

Appreciate if someone could point out what am I doing wrong?

Thanks in advance.

Tech Sawy
  • 91
  • 7

2 Answers2

1
  1. The error sounds like a config issue w/ the Solace setup connection factory.

  2. FYI: seda endpoints can't be counted on in a transaction b/c they are async.

  3. If you really need transactions b/w all steps, I'd place the message back on another solace queue instead of a seda endpoint

Matt Pavlovich
  • 4,087
  • 1
  • 9
  • 17
  • Matt, I have to use SEDA because of defined SLA to process messages but will think about introducing another Solace queue to pass-on messages. – Tech Sawy Oct 07 '16 at 08:36
1

Could not create JMS transaction; nested exception is com.solacesystems.jms.ConfigurationException: Transacted sessions or XA sessions are not supported with direct transport

Solace does not allow transactions that make use of JMS connection factories with direct transport enabled. This is the cause of your exception.

The solution here is to disable direct transport on the connection factory used by your msgProcessor bean to enable transactions to get rid of this exception.

Message is retained on in.solace.queue if exception is raised by sequencer but it is lost if message has been passed from staging queue to SEDA to msgProcessor bean and following exception is thrown.

From http://camel.apache.org/seda.html, it appears that SEDA does not support recovery/transactions.

This component does not implement any kind of persistence or recovery, if the VM terminates while messages are yet to be processed. If you need persistence, reliability or distributed SEDA, try using either JMS or ActiveMQ.

Russell Sim
  • 1,693
  • 2
  • 14
  • 22
  • but message won't be retained in case **VM terminates**, not if some exception is thrown by application. – Tech Sawy Oct 07 '16 at 08:30