JMS Transactions and RequestReply - transactedInOut=true not working?

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

JMS Transactions and RequestReply - transactedInOut=true not working?

jonathanq
I am having an issue with JMS queues and transactions.

I have the following route:

from("queue:incomingqueue")
        .process(getSomeTranslationProcessor())
        .process(getMyPersistanceProcessor())
        .process(getSomeOtherTransformerProcessor())
        .to("queue:outgoingqueue");

The first and third processor just do some simple transformation on the exchange.  The middle processor (myPersistanceProcessor) is the key piece.

It is a processor that sends part of the exchange to another queue and requests a reply back.  It uses a ProducerTemplate and looks like:

Long recordDBId = (Long)producer.sendBody("queue:persistancequeue", ExchangePattern.InOut, objectToPersist);

It is a synchronous process - so the myPersistanceProcessor will wait for a reply back before continuing.

Now - the issue I have is this.  If that InOut part of the route fails for any reason (such as a time out, returns an error etc).  I want to essentially NOT acknowledge the message from the original incoming JMS queue (meaning it will go back on the front of the queue).


I know that if you just do a "queue:incomingqueue?transacted=true" - it will put the message back on the queue if the exchange failed.  However If you add "transacted=true" to the incoming queue in my route - it will never send the message for the RequestReply part.  

Based on the documentation - that is because we must first commit the transaction and then start another.  However there is mention of the value "transactedInOut=true" which seems to imply it will create a transaction that wraps the WHOLE process (including the requestreply).

In practice - using "transactedInOut=true" means that if the producer.sendBody() timesout, it sends an eviction notice for that message - but the original exchange does NOT get put back on the incoming queue.  In fact it disappears altogether.  The Camel JMX bean does not record it as a "Failed Exchange" - even through the log message says it was a failed exchange.  The exposed Camel JMX thinks it was a successful exchange.

Is that how the "transactedInOut=true" is supposed to operate?  Is there any way to tell the incoming queue that we did NOT process the message and have it put back there if it failed?  Is there an error route that would put the original message back on the queue?  Or is that where using the:

onException(Exception.class)
.maximumRedeliveries(-1)

comes into play - as that will cause it to just be re-tried constantly?

Thanks for any help you can offer!
Reply | Threaded
Open this post in threaded view
|

Re: JMS Transactions and RequestReply - transactedInOut=true not working?

Claus Ibsen-2
Hi

Try using a 2nd JMS component for sending. Then its separated from the
1st component.


On Sat, Oct 31, 2009 at 12:26 AM, jonathanq <[hidden email]> wrote:

>
> I am having an issue with JMS queues and transactions.
>
> I have the following route:
>
> from("queue:incomingqueue")
>        .process(getSomeTranslationProcessor())
>        .process(getMyPersistanceProcessor())
>        .process(getSomeOtherTransformerProcessor())
>        .to("queue:outgoingqueue");
>
> The first and third processor just do some simple transformation on the
> exchange.  The middle processor (myPersistanceProcessor) is the key piece.
>
> It is a processor that sends part of the exchange to another queue and
> requests a reply back.  It uses a ProducerTemplate and looks like:
>
> Long recordDBId = (Long)producer.sendBody("queue:persistancequeue",
> ExchangePattern.InOut, objectToPersist);
>
> It is a synchronous process - so the myPersistanceProcessor will wait for a
> reply back before continuing.
>
> Now - the issue I have is this.  If that InOut part of the route fails for
> any reason (such as a time out, returns an error etc).  I want to
> essentially NOT acknowledge the message from the original incoming JMS queue
> (meaning it will go back on the front of the queue).
>
>
> I know that if you just do a "queue:incomingqueue?transacted=true" - it will
> put the message back on the queue if the exchange failed.  However If you
> add "transacted=true" to the incoming queue in my route - it will never send
> the message for the RequestReply part.
>
> Based on the documentation - that is because we must first commit the
> transaction and then start another.  However there is mention of the value
> "transactedInOut=true" which seems to imply it will create a transaction
> that wraps the WHOLE process (including the requestreply).
>
> In practice - using "transactedInOut=true" means that if the
> producer.sendBody() timesout, it sends an eviction notice for that message -
> but the original exchange does NOT get put back on the incoming queue.  In
> fact it disappears altogether.  The Camel JMX bean does not record it as a
> "Failed Exchange" - even through the log message says it was a failed
> exchange.  The exposed Camel JMX thinks it was a successful exchange.
>
> Is that how the "transactedInOut=true" is supposed to operate?  Is there any
> way to tell the incoming queue that we did NOT process the message and have
> it put back there if it failed?  Is there an error route that would put the
> original message back on the queue?  Or is that where using the:
>
> onException(Exception.class)
> .maximumRedeliveries(-1)
>
> comes into play - as that will cause it to just be re-tried constantly?
>
> Thanks for any help you can offer!
> --
> View this message in context: http://old.nabble.com/JMS-Transactions-and-RequestReply---transactedInOut%3Dtrue-not-working--tp26138285p26138285.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>
>



--
Claus Ibsen
Apache Camel Committer

Author of Camel in Action: http://www.manning.com/ibsen/
Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/
Twitter: http://twitter.com/davsclaus
Reply | Threaded
Open this post in threaded view
|

Re: JMS Transactions and RequestReply - transactedInOut=true not working?

Fintan Bolton
Hi Johnathan,

To elaborate on Claus's reply. In general, you cannot really process InOut exchanges inside a transaction (yes, there is a 'transactedInOut' option, but it only applies to a very special use case and is not relevant to your example).

The best approach, as Claus suggested, is to split your route into two parts: one route to handle the 'request' leg of the processing and another route to handle the 'reply' leg of the processing. You need to break up the request/reply queue, 'queue:persistancequeue', into two separate queues that explicitly handle the request and reply legs, e.g. 'queue:requestqueue' and 'queue:replyqueue'.

You can then write your route in the form of two separate transactional routes:

from("queue:incomingqueue?transacted=true")
        .process(getSomeTranslationProcessor())
        .to("queue:requestqueue")

from("queue:replyqueue?transacted=true")
        .process(getSomeOtherTransformerProcessor())
        .to("queue:outgoingqueue");

The exchanges passing through these routes should be of InOnly type. I added the ?transacted=true option just to indicate that both routes are transactional. Of course, you have to do all the additional Spring configuration to make the 'queue' component transactional as well.

Regards,
Fintan


Claus Ibsen-2 wrote
Hi

Try using a 2nd JMS component for sending. Then its separated from the
1st component.


On Sat, Oct 31, 2009 at 12:26 AM, jonathanq <jquail@abebooks.com> wrote:
>
> I am having an issue with JMS queues and transactions.
>
> I have the following route:
>
> from("queue:incomingqueue")
>        .process(getSomeTranslationProcessor())
>        .process(getMyPersistanceProcessor())
>        .process(getSomeOtherTransformerProcessor())
>        .to("queue:outgoingqueue");
>
> The first and third processor just do some simple transformation on the
> exchange.  The middle processor (myPersistanceProcessor) is the key piece.
>
> It is a processor that sends part of the exchange to another queue and
> requests a reply back.  It uses a ProducerTemplate and looks like:
>
> Long recordDBId = (Long)producer.sendBody("queue:persistancequeue",
> ExchangePattern.InOut, objectToPersist);
>
> It is a synchronous process - so the myPersistanceProcessor will wait for a
> reply back before continuing.
>
> Now - the issue I have is this.  If that InOut part of the route fails for
> any reason (such as a time out, returns an error etc).  I want to
> essentially NOT acknowledge the message from the original incoming JMS queue
> (meaning it will go back on the front of the queue).
>
>
> I know that if you just do a "queue:incomingqueue?transacted=true" - it will
> put the message back on the queue if the exchange failed.  However If you
> add "transacted=true" to the incoming queue in my route - it will never send
> the message for the RequestReply part.
>
> Based on the documentation - that is because we must first commit the
> transaction and then start another.  However there is mention of the value
> "transactedInOut=true" which seems to imply it will create a transaction
> that wraps the WHOLE process (including the requestreply).
>
> In practice - using "transactedInOut=true" means that if the
> producer.sendBody() timesout, it sends an eviction notice for that message -
> but the original exchange does NOT get put back on the incoming queue.  In
> fact it disappears altogether.  The Camel JMX bean does not record it as a
> "Failed Exchange" - even through the log message says it was a failed
> exchange.  The exposed Camel JMX thinks it was a successful exchange.
>
> Is that how the "transactedInOut=true" is supposed to operate?  Is there any
> way to tell the incoming queue that we did NOT process the message and have
> it put back there if it failed?  Is there an error route that would put the
> original message back on the queue?  Or is that where using the:
>
> onException(Exception.class)
> .maximumRedeliveries(-1)
>
> comes into play - as that will cause it to just be re-tried constantly?
>
> Thanks for any help you can offer!
> --
> View this message in context: http://old.nabble.com/JMS-Transactions-and-RequestReply---transactedInOut%3Dtrue-not-working--tp26138285p26138285.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>
>



--
Claus Ibsen
Apache Camel Committer

Author of Camel in Action: http://www.manning.com/ibsen/
Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/
Twitter: http://twitter.com/davsclaus
Reply | Threaded
Open this post in threaded view
|

Re: JMS Transactions and RequestReply - transactedInOut=true not working?

jonathanq
Thanks for the reply - I was only able to get my route working by using a Spring Transaction Manager to open a new transaction (using PROPOGATION_NOT_SUPPORTED) to do the actual publish request/reply part of the route (just wrapped the producer template publish in this transaction).  That worked.

However it opened up a few other issues that we were not comfortable handling (such as stray database records if the persistence succeeded but other parts of the processing failed).  Although this overall situation could potentially be handled with a JTA product that would encompass the processing in this route and also the DB persistance handled by the other process on the other queue.

We changed our approach to remove the Request/Reply requirement from our route.


My only remaining concern is just that the documentation for the Transaction support and RequestReply functionality left me thinking this was a bug in my code or a bug in the Camel code.  It seemed to me from reading the documentation that sending a RequestReply message in a transaction would work - but would just not be part of the transaction (meaning - if the transaction rolled back, just accept the fact that whatever happened on that other process will NOT roll back).

In reality - no matter what I did, I could not get the message to publish and get a reply while operating in a transaction.  It was only after I introduced a Spring transaction in my processor that I was able to force the message to be published and get a reply.

Perhaps a new option to "force" a publish to occur even in a transaction..with the clear understanding that doing so will mean that part is NOT going to be part of the transaction.  Indeed the documentation only states using TransactedInOut=true will cause it to not operate in a transaction...where in reality it would not even send the request.

Specifically this part from: http://camel.apache.org/jms.html  - the bolded part is what confused me as it seemed to contradict what was right above it stating that you can't use transactions at all.  The solution here is probably just making sure that the purpose for "transactedInOut=true" is clearly explained.  As of right now I don't really understand what it is for, where it can be used, and what it will accomplish.

Transaction and Request Reply over JMS

Note that when using Request Reply over JMS you cannot use a single transaction; as JMS will not send any messages until a commit is performed, the server side won't receive anything at all until the transaction commits. So, with request/response you must commit a transaction after sending the first request and then use a separate transaction for receiving the response.

This is why the transacted property applies only to the InOnly message Exchange Pattern (MEP). If you want to use transactions for the InOut MEP as well, you must set transactedInOut=true.

To recap: if you have transacted=true, transactedInOut=false and are sending an InOut, the Exchange will not use transactions.



In any event - thank you for your suggestion!

Fintan Bolton wrote
Hi Johnathan,

To elaborate on Claus's reply. In general, you cannot really process InOut exchanges inside a transaction (yes, there is a 'transactedInOut' option, but it only applies to a very special use case and is not relevant to your example).

The best approach, as Claus suggested, is to split your route into two parts: one route to handle the 'request' leg of the processing and another route to handle the 'reply' leg of the processing. You need to break up the request/reply queue, 'queue:persistancequeue', into two separate queues that explicitly handle the request and reply legs, e.g. 'queue:requestqueue' and 'queue:replyqueue'.

You can then write your route in the form of two separate transactional routes:

from("queue:incomingqueue?transacted=true")
        .process(getSomeTranslationProcessor())
        .to("queue:requestqueue")

from("queue:replyqueue?transacted=true")
        .process(getSomeOtherTransformerProcessor())
        .to("queue:outgoingqueue");

The exchanges passing through these routes should be of InOnly type. I added the ?transacted=true option just to indicate that both routes are transactional. Of course, you have to do all the additional Spring configuration to make the 'queue' component transactional as well.

Regards,
Fintan


Claus Ibsen-2 wrote
Hi

Try using a 2nd JMS component for sending. Then its separated from the
1st component.


On Sat, Oct 31, 2009 at 12:26 AM, jonathanq <jquail@abebooks.com> wrote:
>
> I am having an issue with JMS queues and transactions.
>
> I have the following route:
>
> from("queue:incomingqueue")
>        .process(getSomeTranslationProcessor())
>        .process(getMyPersistanceProcessor())
>        .process(getSomeOtherTransformerProcessor())
>        .to("queue:outgoingqueue");
>
> The first and third processor just do some simple transformation on the
> exchange.  The middle processor (myPersistanceProcessor) is the key piece.
>
> It is a processor that sends part of the exchange to another queue and
> requests a reply back.  It uses a ProducerTemplate and looks like:
>
> Long recordDBId = (Long)producer.sendBody("queue:persistancequeue",
> ExchangePattern.InOut, objectToPersist);
>
> It is a synchronous process - so the myPersistanceProcessor will wait for a
> reply back before continuing.
>
> Now - the issue I have is this.  If that InOut part of the route fails for
> any reason (such as a time out, returns an error etc).  I want to
> essentially NOT acknowledge the message from the original incoming JMS queue
> (meaning it will go back on the front of the queue).
>
>
> I know that if you just do a "queue:incomingqueue?transacted=true" - it will
> put the message back on the queue if the exchange failed.  However If you
> add "transacted=true" to the incoming queue in my route - it will never send
> the message for the RequestReply part.
>
> Based on the documentation - that is because we must first commit the
> transaction and then start another.  However there is mention of the value
> "transactedInOut=true" which seems to imply it will create a transaction
> that wraps the WHOLE process (including the requestreply).
>
> In practice - using "transactedInOut=true" means that if the
> producer.sendBody() timesout, it sends an eviction notice for that message -
> but the original exchange does NOT get put back on the incoming queue.  In
> fact it disappears altogether.  The Camel JMX bean does not record it as a
> "Failed Exchange" - even through the log message says it was a failed
> exchange.  The exposed Camel JMX thinks it was a successful exchange.
>
> Is that how the "transactedInOut=true" is supposed to operate?  Is there any
> way to tell the incoming queue that we did NOT process the message and have
> it put back there if it failed?  Is there an error route that would put the
> original message back on the queue?  Or is that where using the:
>
> onException(Exception.class)
> .maximumRedeliveries(-1)
>
> comes into play - as that will cause it to just be re-tried constantly?
>
> Thanks for any help you can offer!
> --
> View this message in context: http://old.nabble.com/JMS-Transactions-and-RequestReply---transactedInOut%3Dtrue-not-working--tp26138285p26138285.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>
>



--
Claus Ibsen
Apache Camel Committer

Author of Camel in Action: http://www.manning.com/ibsen/
Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/
Twitter: http://twitter.com/davsclaus
Reply | Threaded
Open this post in threaded view
|

Re: JMS Transactions and RequestReply - transactedInOut=true not working?

Fintan Bolton
It sounds like your experience is similar to what I found when I tried experimenting with the transactedInOut option. In summary, what I found is that when I enabled transactedInOut on a producer endpoint (i.e. in a to(..) call) one of the following things occurred:

. If there was an existing transaction associated with the current thread, the producer endpoint would hang.

. If there was no existing transaction associated with the current thread, the producer endpoint would create a local transaction, whose scope was limited to pushing the exchange onto the outgoing request queue.

Since I didn't think this behaviour was very useful, I created a ticket in the Camel JIRA database, which you might be interested in reading: http://issues.apache.org/activemq/browse/CAMEL-2001 

In the end, I found myself in agreement with Marat. I think the best approach to handling request-reply semantics (InOut exchange pattern) in a transactional route with JMS endpoints is simply to create two separate routes: one for the request leg and another for the reply leg. As far as I can figure, this seems to be the only way you can ensure transactional integrity over the whole route.

Regards,
Fintan

jonathanq wrote
Thanks for the reply - I was only able to get my route working by using a Spring Transaction Manager to open a new transaction (using PROPOGATION_NOT_SUPPORTED) to do the actual publish request/reply part of the route (just wrapped the producer template publish in this transaction).  That worked.

However it opened up a few other issues that we were not comfortable handling (such as stray database records if the persistence succeeded but other parts of the processing failed).  Although this overall situation could potentially be handled with a JTA product that would encompass the processing in this route and also the DB persistance handled by the other process on the other queue.

We changed our approach to remove the Request/Reply requirement from our route.


My only remaining concern is just that the documentation for the Transaction support and RequestReply functionality left me thinking this was a bug in my code or a bug in the Camel code.  It seemed to me from reading the documentation that sending a RequestReply message in a transaction would work - but would just not be part of the transaction (meaning - if the transaction rolled back, just accept the fact that whatever happened on that other process will NOT roll back).

In reality - no matter what I did, I could not get the message to publish and get a reply while operating in a transaction.  It was only after I introduced a Spring transaction in my processor that I was able to force the message to be published and get a reply.

Perhaps a new option to "force" a publish to occur even in a transaction..with the clear understanding that doing so will mean that part is NOT going to be part of the transaction.  Indeed the documentation only states using TransactedInOut=true will cause it to not operate in a transaction...where in reality it would not even send the request.

Specifically this part from: http://camel.apache.org/jms.html  - the bolded part is what confused me as it seemed to contradict what was right above it stating that you can't use transactions at all.  The solution here is probably just making sure that the purpose for "transactedInOut=true" is clearly explained.  As of right now I don't really understand what it is for, where it can be used, and what it will accomplish.

Transaction and Request Reply over JMS

Note that when using Request Reply over JMS you cannot use a single transaction; as JMS will not send any messages until a commit is performed, the server side won't receive anything at all until the transaction commits. So, with request/response you must commit a transaction after sending the first request and then use a separate transaction for receiving the response.

This is why the transacted property applies only to the InOnly message Exchange Pattern (MEP). If you want to use transactions for the InOut MEP as well, you must set transactedInOut=true.

To recap: if you have transacted=true, transactedInOut=false and are sending an InOut, the Exchange will not use transactions.



In any event - thank you for your suggestion!

Fintan Bolton wrote
Hi Johnathan,

To elaborate on Claus's reply. In general, you cannot really process InOut exchanges inside a transaction (yes, there is a 'transactedInOut' option, but it only applies to a very special use case and is not relevant to your example).

The best approach, as Claus suggested, is to split your route into two parts: one route to handle the 'request' leg of the processing and another route to handle the 'reply' leg of the processing. You need to break up the request/reply queue, 'queue:persistancequeue', into two separate queues that explicitly handle the request and reply legs, e.g. 'queue:requestqueue' and 'queue:replyqueue'.

You can then write your route in the form of two separate transactional routes:

from("queue:incomingqueue?transacted=true")
        .process(getSomeTranslationProcessor())
        .to("queue:requestqueue")

from("queue:replyqueue?transacted=true")
        .process(getSomeOtherTransformerProcessor())
        .to("queue:outgoingqueue");

The exchanges passing through these routes should be of InOnly type. I added the ?transacted=true option just to indicate that both routes are transactional. Of course, you have to do all the additional Spring configuration to make the 'queue' component transactional as well.

Regards,
Fintan


Claus Ibsen-2 wrote
Hi

Try using a 2nd JMS component for sending. Then its separated from the
1st component.


On Sat, Oct 31, 2009 at 12:26 AM, jonathanq <jquail@abebooks.com> wrote:
>
> I am having an issue with JMS queues and transactions.
>
> I have the following route:
>
> from("queue:incomingqueue")
>        .process(getSomeTranslationProcessor())
>        .process(getMyPersistanceProcessor())
>        .process(getSomeOtherTransformerProcessor())
>        .to("queue:outgoingqueue");
>
> The first and third processor just do some simple transformation on the
> exchange.  The middle processor (myPersistanceProcessor) is the key piece.
>
> It is a processor that sends part of the exchange to another queue and
> requests a reply back.  It uses a ProducerTemplate and looks like:
>
> Long recordDBId = (Long)producer.sendBody("queue:persistancequeue",
> ExchangePattern.InOut, objectToPersist);
>
> It is a synchronous process - so the myPersistanceProcessor will wait for a
> reply back before continuing.
>
> Now - the issue I have is this.  If that InOut part of the route fails for
> any reason (such as a time out, returns an error etc).  I want to
> essentially NOT acknowledge the message from the original incoming JMS queue
> (meaning it will go back on the front of the queue).
>
>
> I know that if you just do a "queue:incomingqueue?transacted=true" - it will
> put the message back on the queue if the exchange failed.  However If you
> add "transacted=true" to the incoming queue in my route - it will never send
> the message for the RequestReply part.
>
> Based on the documentation - that is because we must first commit the
> transaction and then start another.  However there is mention of the value
> "transactedInOut=true" which seems to imply it will create a transaction
> that wraps the WHOLE process (including the requestreply).
>
> In practice - using "transactedInOut=true" means that if the
> producer.sendBody() timesout, it sends an eviction notice for that message -
> but the original exchange does NOT get put back on the incoming queue.  In
> fact it disappears altogether.  The Camel JMX bean does not record it as a
> "Failed Exchange" - even through the log message says it was a failed
> exchange.  The exposed Camel JMX thinks it was a successful exchange.
>
> Is that how the "transactedInOut=true" is supposed to operate?  Is there any
> way to tell the incoming queue that we did NOT process the message and have
> it put back there if it failed?  Is there an error route that would put the
> original message back on the queue?  Or is that where using the:
>
> onException(Exception.class)
> .maximumRedeliveries(-1)
>
> comes into play - as that will cause it to just be re-tried constantly?
>
> Thanks for any help you can offer!
> --
> View this message in context: http://old.nabble.com/JMS-Transactions-and-RequestReply---transactedInOut%3Dtrue-not-working--tp26138285p26138285.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>
>



--
Claus Ibsen
Apache Camel Committer

Author of Camel in Action: http://www.manning.com/ibsen/
Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/
Twitter: http://twitter.com/davsclaus
Reply | Threaded
Open this post in threaded view
|

Re: JMS Transactions and RequestReply - transactedInOut=true not working?

Claus Ibsen-2
Hi

Yeah it may be a good idea to remove that transactedInOut option. I
cant even remember why it was added in the first place.
Maybe checking the source commit logs will reveal that.

And we love contributions so you can for example help improve the wiki
documentation, write a cookbook, blog entry etc.
http://camel.apache.org/contributing.html



On Thu, Nov 5, 2009 at 12:05 PM, Fintan Bolton <[hidden email]> wrote:

>
> It sounds like your experience is similar to what I found when I tried
> experimenting with the transactedInOut option. In summary, what I found is
> that when I enabled transactedInOut on a producer endpoint (i.e. in a to(..)
> call) one of the following things occurred:
>
> . If there was an existing transaction associated with the current thread,
> the producer endpoint would hang.
>
> . If there was no existing transaction associated with the current thread,
> the producer endpoint would create a local transaction, whose scope was
> limited to pushing the exchange onto the outgoing request queue.
>
> Since I didn't think this behaviour was very useful, I created a ticket in
> the Camel JIRA database, which you might be interested in reading:
> http://issues.apache.org/activemq/browse/CAMEL-2001
>
> In the end, I found myself in agreement with Marat. I think the best
> approach to handling request-reply semantics (InOut exchange pattern) in a
> transactional route with JMS endpoints is simply to create two separate
> routes: one for the request leg and another for the reply leg. As far as I
> can figure, this seems to be the only way you can ensure transactional
> integrity over the whole route.
>
> Regards,
> Fintan
>
>
> jonathanq wrote:
>>
>> Thanks for the reply - I was only able to get my route working by using a
>> Spring Transaction Manager to open a new transaction (using
>> PROPOGATION_NOT_SUPPORTED) to do the actual publish request/reply part of
>> the route (just wrapped the producer template publish in this
>> transaction).  That worked.
>>
>> However it opened up a few other issues that we were not comfortable
>> handling (such as stray database records if the persistence succeeded but
>> other parts of the processing failed).  Although this overall situation
>> could potentially be handled with a JTA product that would encompass the
>> processing in this route and also the DB persistance handled by the other
>> process on the other queue.
>>
>> We changed our approach to remove the Request/Reply requirement from our
>> route.
>>
>>
>> My only remaining concern is just that the documentation for the
>> Transaction support and RequestReply functionality left me thinking this
>> was a bug in my code or a bug in the Camel code.  It seemed to me from
>> reading the documentation that sending a RequestReply message in a
>> transaction would work - but would just not be part of the transaction
>> (meaning - if the transaction rolled back, just accept the fact that
>> whatever happened on that other process will NOT roll back).
>>
>> In reality - no matter what I did, I could not get the message to publish
>> and get a reply while operating in a transaction.  It was only after I
>> introduced a Spring transaction in my processor that I was able to force
>> the message to be published and get a reply.
>>
>> Perhaps a new option to "force" a publish to occur even in a
>> transaction..with the clear understanding that doing so will mean that
>> part is NOT going to be part of the transaction.  Indeed the documentation
>> only states using TransactedInOut=true will cause it to not operate in a
>> transaction...where in reality it would not even send the request.
>>
>> Specifically this part from: http://camel.apache.org/jms.html  - the
>> bolded part is what confused me as it seemed to contradict what was right
>> above it stating that you can't use transactions at all.  The solution
>> here is probably just making sure that the purpose for
>> "transactedInOut=true" is clearly explained.  As of right now I don't
>> really understand what it is for, where it can be used, and what it will
>> accomplish.
>>
>> Transaction and Request Reply over JMS
>>
>> Note that when using Request Reply over JMS you cannot use a single
>> transaction; as JMS will not send any messages until a commit is
>> performed, the server side won't receive anything at all until the
>> transaction commits. So, with request/response you must commit a
>> transaction after sending the first request and then use a separate
>> transaction for receiving the response.
>>
>> This is why the transacted property applies only to the InOnly message
>> Exchange Pattern (MEP). If you want to use transactions for the InOut MEP
>> as well, you must set transactedInOut=true.
>>
>> To recap: if you have transacted=true, transactedInOut=false and are
>> sending an InOut, the Exchange will not use transactions.
>>
>>
>> In any event - thank you for your suggestion!
>>
>>
>> Fintan Bolton wrote:
>>>
>>> Hi Johnathan,
>>>
>>> To elaborate on Claus's reply. In general, you cannot really process
>>> InOut exchanges inside a transaction (yes, there is a 'transactedInOut'
>>> option, but it only applies to a very special use case and is not
>>> relevant to your example).
>>>
>>> The best approach, as Claus suggested, is to split your route into two
>>> parts: one route to handle the 'request' leg of the processing and
>>> another route to handle the 'reply' leg of the processing. You need to
>>> break up the request/reply queue, 'queue:persistancequeue', into two
>>> separate queues that explicitly handle the request and reply legs, e.g.
>>> 'queue:requestqueue' and 'queue:replyqueue'.
>>>
>>> You can then write your route in the form of two separate transactional
>>> routes:
>>>
>>> from("queue:incomingqueue?transacted=true")
>>>         .process(getSomeTranslationProcessor())
>>>         .to("queue:requestqueue")
>>>
>>> from("queue:replyqueue?transacted=true")
>>>         .process(getSomeOtherTransformerProcessor())
>>>         .to("queue:outgoingqueue");
>>>
>>> The exchanges passing through these routes should be of InOnly type. I
>>> added the ?transacted=true option just to indicate that both routes are
>>> transactional. Of course, you have to do all the additional Spring
>>> configuration to make the 'queue' component transactional as well.
>>>
>>> Regards,
>>> Fintan
>>>
>>>
>>>
>>> Claus Ibsen-2 wrote:
>>>>
>>>> Hi
>>>>
>>>> Try using a 2nd JMS component for sending. Then its separated from the
>>>> 1st component.
>>>>
>>>>
>>>> On Sat, Oct 31, 2009 at 12:26 AM, jonathanq <[hidden email]> wrote:
>>>>>
>>>>> I am having an issue with JMS queues and transactions.
>>>>>
>>>>> I have the following route:
>>>>>
>>>>> from("queue:incomingqueue")
>>>>>        .process(getSomeTranslationProcessor())
>>>>>        .process(getMyPersistanceProcessor())
>>>>>        .process(getSomeOtherTransformerProcessor())
>>>>>        .to("queue:outgoingqueue");
>>>>>
>>>>> The first and third processor just do some simple transformation on the
>>>>> exchange.  The middle processor (myPersistanceProcessor) is the key
>>>>> piece.
>>>>>
>>>>> It is a processor that sends part of the exchange to another queue and
>>>>> requests a reply back.  It uses a ProducerTemplate and looks like:
>>>>>
>>>>> Long recordDBId = (Long)producer.sendBody("queue:persistancequeue",
>>>>> ExchangePattern.InOut, objectToPersist);
>>>>>
>>>>> It is a synchronous process - so the myPersistanceProcessor will wait
>>>>> for a
>>>>> reply back before continuing.
>>>>>
>>>>> Now - the issue I have is this.  If that InOut part of the route fails
>>>>> for
>>>>> any reason (such as a time out, returns an error etc).  I want to
>>>>> essentially NOT acknowledge the message from the original incoming JMS
>>>>> queue
>>>>> (meaning it will go back on the front of the queue).
>>>>>
>>>>>
>>>>> I know that if you just do a "queue:incomingqueue?transacted=true" - it
>>>>> will
>>>>> put the message back on the queue if the exchange failed.  However If
>>>>> you
>>>>> add "transacted=true" to the incoming queue in my route - it will never
>>>>> send
>>>>> the message for the RequestReply part.
>>>>>
>>>>> Based on the documentation - that is because we must first commit the
>>>>> transaction and then start another.  However there is mention of the
>>>>> value
>>>>> "transactedInOut=true" which seems to imply it will create a
>>>>> transaction
>>>>> that wraps the WHOLE process (including the requestreply).
>>>>>
>>>>> In practice - using "transactedInOut=true" means that if the
>>>>> producer.sendBody() timesout, it sends an eviction notice for that
>>>>> message -
>>>>> but the original exchange does NOT get put back on the incoming queue.
>>>>>  In
>>>>> fact it disappears altogether.  The Camel JMX bean does not record it
>>>>> as a
>>>>> "Failed Exchange" - even through the log message says it was a failed
>>>>> exchange.  The exposed Camel JMX thinks it was a successful exchange.
>>>>>
>>>>> Is that how the "transactedInOut=true" is supposed to operate?  Is
>>>>> there any
>>>>> way to tell the incoming queue that we did NOT process the message and
>>>>> have
>>>>> it put back there if it failed?  Is there an error route that would put
>>>>> the
>>>>> original message back on the queue?  Or is that where using the:
>>>>>
>>>>> onException(Exception.class)
>>>>> .maximumRedeliveries(-1)
>>>>>
>>>>> comes into play - as that will cause it to just be re-tried constantly?
>>>>>
>>>>> Thanks for any help you can offer!
>>>>> --
>>>>> View this message in context:
>>>>> http://old.nabble.com/JMS-Transactions-and-RequestReply---transactedInOut%3Dtrue-not-working--tp26138285p26138285.html
>>>>> Sent from the Camel - Users mailing list archive at Nabble.com.
>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Claus Ibsen
>>>> Apache Camel Committer
>>>>
>>>> Author of Camel in Action: http://www.manning.com/ibsen/
>>>> Open Source Integration: http://fusesource.com
>>>> Blog: http://davsclaus.blogspot.com/
>>>> Twitter: http://twitter.com/davsclaus
>>>>
>>>>
>>>
>>>
>>
>>
>
> --
> View this message in context: http://old.nabble.com/JMS-Transactions-and-RequestReply---transactedInOut%3Dtrue-not-working--tp26138285p26211223.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>
>



--
Claus Ibsen
Apache Camel Committer

Author of Camel in Action: http://www.manning.com/ibsen/
Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/
Twitter: http://twitter.com/davsclaus