[
https://issues.apache.org/activemq/browse/CAMEL-2001?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=54118#action_54118
]
Fintan Bolton commented on CAMEL-2001:
--------------------------------------
Marat,
Some replies to your points:
1. I think we might be talking at cross purposes on this point. I didn't
realize that it would be possible for the route to process multiple messages
within the context of a single transaction. As for the example you quote, I am
talking about a transacted route like this:
{{from("jmstx:queue:source").to("jmstx:queue:destination")}}, where {{jmstx}}
is a transacted instance of the JMS component. The suggestion I made is to
process a message as follows: the transaction starts, the consumer pulls a
message from {{source}}, the producer sends the message to {{destination}}, and
the producer then commits the transaction. This does involve two updates of the
persistent JMS resource: pulling the message off the {{source}} queue and
pushing the message onto the {{destination}} queue.
2. Good point! I think you have hit the nail on the head. Now that I think of
it, I cannot figure out how you would make the whole request/reply sequence
reliable. Even if the destination endpoint (that the producer sent to) was
reliable and calculated the reply, how would the router recover the reply once
it started up again? The producer endpoint is not going to poll for a missing
reply once the router gets rebooted, so the reply will be lost.
3. Using two transacted InOnly routes sounds like excatly the right approach to
take. In the scenario with the crashing router, it would actually be possible
to recover in this case, because the reply queue would be polled by a consumer
endpoint as soon as the router rebooted.
By the way, I can think of one hybrid InOut/InOnly scenario where it does make
sense for the route to be transactional. For example:
{code}
from("jmstx:queue:inOutSource")
.to(ExchangePattern.InOnly, "jmstx:queue:log")
.to(ExchangePattern.InOnly, "jmstx:queue:confirm")
.process(myProcessor);
{code}
When you run this transacted route, no deadlock occurs, because the producers
are constrained to use the _InOnly_ pattern.
> Transactions do not work properly with JMS producer endpoint when processing
> InOut exchanges
> --------------------------------------------------------------------------------------------
>
> Key: CAMEL-2001
> URL: https://issues.apache.org/activemq/browse/CAMEL-2001
> Project: Apache Camel
> Issue Type: Bug
> Components: camel-jms
> Affects Versions: 2.0.0
> Reporter: Fintan Bolton
> Fix For: Future
>
>
> You cannot really use transactions with a JMS producer endpoint when
> processing _InOut_ exchanges. Depending on the scenario, the route either
> hangs or the implemented behavior is not very useful.
> Here is a summary of the current (not very useful) behavior:
> After experimenting with JMS transacted endpoints for a bit and looking at
> the source, here is what I found the behavior to be for JMS producer
> endpoints:
> # On the request leg (sending the JMS message), if there is no existing
> transaction context, the producer will either create a transaction for
> sending the message (if {{transactedInOut=true}} or not (if
> {{transactedInOut=false}}). In any case, since the transaction only lasts as
> long as it takes to push the message onto the outoing queue, it is not
> particularly interesting. Meaningful transactions are generally used to
> bracket multiple (i.e. >1) updates of a persistent resource.
> # On the request leg, if there *is* an existing transaction context, the
> producer joins the current transaction (irrespective of the value of
> {{transactedInOut}}), provisionally writes the message to the outgoing queue,
> and then starts waiting for the reply. In this case, the route hangs, because
> the send is never committed.
> # On the reply leg, the message is received in a separate thread. This step
> is transactional, but the transaction ends as soon as the message has been
> pulled off the queue, so it is also not very interesting.
> Here is what I think would be useful behavior for a JMS producer endpoint:
> # On the request leg, if there is an existing transaction context, the
> producer joins the current transaction, provisionally writes the message to
> the outgoing queue, and then *commits* the current transaction directly
> afterwards. This prevents the route from hanging. *Note:* There is some code
> in the {{CamelJmsTemplate}} class looks like it was intended to do this, but
> it currently does not work. See child issue for more details.
> # On the reply leg, create a new transaction in the main thread that includes
> the action of pulling the reply off the incoming queue. This would require
> that the reply be received in the main thread, not a sub-thread (as
> currently). Subsequent nodes in the route could then participate in this
> transaction. Admittedly, this would be a tricky feature to implement, because
> it would involve making a big change to the producer's threading model.
> I'm shortly going to add a couple of child JIRAs here to explain some related
> issues.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.