You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by nezor <Ky...@oeconnection.com> on 2013/08/16 16:39:01 UTC

Odd AMQ Transaction Behavior

I'm attempting to send a message from an AMQ Virtual Topic consumer to an
http endpoint using http4 with transactions. When the http service is down
http4 returns a org.apache.http.conn.HttpHostConnectException. When this
exception is thrown I would like the transaction to be rolled back and the
failed message to be placed back in the queue. AMQ then has a redelivery
policy for these messages. All other exceptions are marked has handled and
placed in a DLQ.

The route looks like this,
<route id="service.requests.consumer" streamCache="true">
	<from
uri="activemq:Consumer.service-requests.VirtualTopic.service.requests"/>
	<convertBodyTo type="String" />
	<setHeader headerName="CamelHttpMethod">
		<constant>POST</constant>
	</setHeader>
	<transacted ref="PROPAGATION_REQUIRES_NEW"/>
	<to uri="http4:{{service.requests.httpproduceruri}}"/>
	<onException>
		<exception>org.apache.http.conn.HttpHostConnectException</exception>
		<rollback markRollbackOnly="true"/>
	</onException>
	<onException>
		<exception>java.lang.Exception</exception>
		<handled>
		  <constant>true</constant>
		</handled>
		<transform>
	  		<simple>{Exception:${exception}, Request:${body}}</simple>
		</transform>
		<to uri="activemq:queue:service-requests.dlq"/>
	</onException>
</route>

The DQL piece of the route works perfectly. But I'm not seeing what I would
expect from the rollback. My expectation was that by using <rollback
markRollbackOnly="true"/> I should see no exception when I do the rollback.
However this is not the case, when I look at the log I see a
RollbackExchangeException and I don't know why.

org.apache.camel.RuntimeCamelException:
org.apache.camel.RollbackExchangeException: Intended rollback.
Exchange[Message: ]
	at
org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:1157)[88:org.apache.camel.camel-core:2.8.0.fuse-07-15]
	at
org.apache.camel.component.jms.EndpointMessageListener$EndpointMessageListenerAsyncCallback.done(EndpointMessageListener.java:174)[93:org.apache.camel.camel-jms:2.8.0.fuse-07-15]
	at
org.apache.camel.component.jms.EndpointMessageListener.onMessage(EndpointMessageListener.java:110)[93:org.apache.camel.camel-jms:2.8.0.fuse-07-15]
	at
org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:560)[94:org.springframework.jms:3.0.5.RELEASE]
	at
org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:498)[94:org.springframework.jms:3.0.5.RELEASE]
	at
org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:467)[94:org.springframework.jms:3.0.5.RELEASE]
	at
org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:325)[94:org.springframework.jms:3.0.5.RELEASE]
	at
org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:243)[94:org.springframework.jms:3.0.5.RELEASE]
	at
org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1058)[94:org.springframework.jms:3.0.5.RELEASE]
	at
org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1050)[94:org.springframework.jms:3.0.5.RELEASE]
	at
org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:947)[94:org.springframework.jms:3.0.5.RELEASE]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown
Source)[:1.7.0_07]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown
Source)[:1.7.0_07]
	at java.lang.Thread.run(Unknown Source)[:1.7.0_07]

Is there something I'm missing between the AMQ transaction and the camel
route? Any help would be greatly appreciated, thank you.



--
View this message in context: http://camel.465427.n5.nabble.com/Odd-AMQ-Transaction-Behavior-tp5737418.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Odd AMQ Transaction Behavior

Posted by Christian Posta <ch...@gmail.com>.
So markRollbackOnly() will not throw an exception, but you're already in an
exception block. So you should mark the exception as handled == true.


On Fri, Aug 16, 2013 at 7:39 AM, nezor <Ky...@oeconnection.com>wrote:

> I'm attempting to send a message from an AMQ Virtual Topic consumer to an
> http endpoint using http4 with transactions. When the http service is down
> http4 returns a org.apache.http.conn.HttpHostConnectException. When this
> exception is thrown I would like the transaction to be rolled back and the
> failed message to be placed back in the queue. AMQ then has a redelivery
> policy for these messages. All other exceptions are marked has handled and
> placed in a DLQ.
>
> The route looks like this,
> <route id="service.requests.consumer" streamCache="true">
>         <from
> uri="activemq:Consumer.service-requests.VirtualTopic.service.requests"/>
>         <convertBodyTo type="String" />
>         <setHeader headerName="CamelHttpMethod">
>                 <constant>POST</constant>
>         </setHeader>
>         <transacted ref="PROPAGATION_REQUIRES_NEW"/>
>         <to uri="http4:{{service.requests.httpproduceruri}}"/>
>         <onException>
>
> <exception>org.apache.http.conn.HttpHostConnectException</exception>
>                 <rollback markRollbackOnly="true"/>
>         </onException>
>         <onException>
>                 <exception>java.lang.Exception</exception>
>                 <handled>
>                   <constant>true</constant>
>                 </handled>
>                 <transform>
>                         <simple>{Exception:${exception},
> Request:${body}}</simple>
>                 </transform>
>                 <to uri="activemq:queue:service-requests.dlq"/>
>         </onException>
> </route>
>
> The DQL piece of the route works perfectly. But I'm not seeing what I would
> expect from the rollback. My expectation was that by using <rollback
> markRollbackOnly="true"/> I should see no exception when I do the rollback.
> However this is not the case, when I look at the log I see a
> RollbackExchangeException and I don't know why.
>
> org.apache.camel.RuntimeCamelException:
> org.apache.camel.RollbackExchangeException: Intended rollback.
> Exchange[Message: ]
>         at
>
> org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:1157)[88:org.apache.camel.camel-core:2.8.0.fuse-07-15]
>         at
>
> org.apache.camel.component.jms.EndpointMessageListener$EndpointMessageListenerAsyncCallback.done(EndpointMessageListener.java:174)[93:org.apache.camel.camel-jms:2.8.0.fuse-07-15]
>         at
>
> org.apache.camel.component.jms.EndpointMessageListener.onMessage(EndpointMessageListener.java:110)[93:org.apache.camel.camel-jms:2.8.0.fuse-07-15]
>         at
>
> org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:560)[94:org.springframework.jms:3.0.5.RELEASE]
>         at
>
> org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:498)[94:org.springframework.jms:3.0.5.RELEASE]
>         at
>
> org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:467)[94:org.springframework.jms:3.0.5.RELEASE]
>         at
>
> org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:325)[94:org.springframework.jms:3.0.5.RELEASE]
>         at
>
> org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:243)[94:org.springframework.jms:3.0.5.RELEASE]
>         at
>
> org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1058)[94:org.springframework.jms:3.0.5.RELEASE]
>         at
>
> org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1050)[94:org.springframework.jms:3.0.5.RELEASE]
>         at
>
> org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:947)[94:org.springframework.jms:3.0.5.RELEASE]
>         at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown
> Source)[:1.7.0_07]
>         at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown
> Source)[:1.7.0_07]
>         at java.lang.Thread.run(Unknown Source)[:1.7.0_07]
>
> Is there something I'm missing between the AMQ transaction and the camel
> route? Any help would be greatly appreciated, thank you.
>
>
>
> --
> View this message in context:
> http://camel.465427.n5.nabble.com/Odd-AMQ-Transaction-Behavior-tp5737418.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
>



-- 
*Christian Posta*
http://www.christianposta.com/blog
twitter: @christianposta

Re: Odd AMQ Transaction Behavior

Posted by nezor <Ky...@oeconnection.com>.
The exception is being logged as an error and there are two warnings as well.
The transaction rollback warning makes sense. Then the exception seems to
trigger the second warning because I do not have a custom ErrorHandler
configured. 

Sadly adding handled = true did not change this behavior.

Trace from servicemix
08:07:47,841 | WARN  | ecutor.requests] | TransactionErrorHandler          |
91 - org.apache.camel.camel-spring - 2.8.0.fuse-07-15 | Rollback exchangeId:
ID-63080-1376659093317-30-11 due: Connection to http://localhost:8080
refused
08:07:47,843 | ERROR | ecutor.requests] | EndpointMessageListener          |
88 - org.apache.camel.camel-core - 2.8.0.fuse-07-15 | Caused by:
[org.apache.camel.RuntimeCamelException -
org.apache.camel.RollbackExchangeException: Intended rollback.
Exchange[Message: ]]
08:07:47,843 | WARN  | ecutor.requests] | JmsMessageListenerContainer      |
94 - org.springframework.jms - 3.0.5.RELEASE | Execution of JMS message
listener failed, and no ErrorHandler has been set.
org.apache.camel.RuntimeCamelException:
org.apache.camel.RollbackExchangeException: Intended rollback.
Exchange[Message: ]
	at
org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:1157)[88:org.apache.camel.camel-core:2.8.0.fuse-07-15]
	at
org.apache.camel.component.jms.EndpointMessageListener$EndpointMessageListenerAsyncCallback.done(EndpointMessageListener.java:174)[93:org.apache.camel.camel-jms:2.8.0.fuse-07-15]
	at
org.apache.camel.component.jms.EndpointMessageListener.onMessage(EndpointMessageListener.java:110)[93:org.apache.camel.camel-jms:2.8.0.fuse-07-15]
	at
org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:560)[94:org.springframework.jms:3.0.5.RELEASE]
	at
org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:498)[94:org.springframework.jms:3.0.5.RELEASE]
	at
org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:467)[94:org.springframework.jms:3.0.5.RELEASE]
	at
org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:325)[94:org.springframework.jms:3.0.5.RELEASE]
	at
org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:243)[94:org.springframework.jms:3.0.5.RELEASE]
	at
org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1058)[94:org.springframework.jms:3.0.5.RELEASE]
	at
org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1050)[94:org.springframework.jms:3.0.5.RELEASE]
	at
org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:947)[94:org.springframework.jms:3.0.5.RELEASE]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown
Source)[:1.7.0_07]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown
Source)[:1.7.0_07]
	at java.lang.Thread.run(Unknown Source)[:1.7.0_07]
Caused by: org.apache.camel.RollbackExchangeException: Intended rollback.
Exchange[Message: ]



--
View this message in context: http://camel.465427.n5.nabble.com/Odd-AMQ-Transaction-Behavior-tp5737418p5737508.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Odd AMQ Transaction Behavior

Posted by Claus Ibsen <cl...@gmail.com>.
For spring to rollback the TX it has to have a runtime exception being
throw from its doInTransaction method. So Camel does that under the
hood.

The stacktrace you see at what level is it logged? It may be logged at
DEBUG level or possible Spring itself logging it, and not Camel?

On Fri, Aug 16, 2013 at 4:39 PM, nezor <Ky...@oeconnection.com> wrote:
> I'm attempting to send a message from an AMQ Virtual Topic consumer to an
> http endpoint using http4 with transactions. When the http service is down
> http4 returns a org.apache.http.conn.HttpHostConnectException. When this
> exception is thrown I would like the transaction to be rolled back and the
> failed message to be placed back in the queue. AMQ then has a redelivery
> policy for these messages. All other exceptions are marked has handled and
> placed in a DLQ.
>
> The route looks like this,
> <route id="service.requests.consumer" streamCache="true">
>         <from
> uri="activemq:Consumer.service-requests.VirtualTopic.service.requests"/>
>         <convertBodyTo type="String" />
>         <setHeader headerName="CamelHttpMethod">
>                 <constant>POST</constant>
>         </setHeader>
>         <transacted ref="PROPAGATION_REQUIRES_NEW"/>
>         <to uri="http4:{{service.requests.httpproduceruri}}"/>
>         <onException>
>                 <exception>org.apache.http.conn.HttpHostConnectException</exception>
>                 <rollback markRollbackOnly="true"/>
>         </onException>
>         <onException>
>                 <exception>java.lang.Exception</exception>
>                 <handled>
>                   <constant>true</constant>
>                 </handled>
>                 <transform>
>                         <simple>{Exception:${exception}, Request:${body}}</simple>
>                 </transform>
>                 <to uri="activemq:queue:service-requests.dlq"/>
>         </onException>
> </route>
>
> The DQL piece of the route works perfectly. But I'm not seeing what I would
> expect from the rollback. My expectation was that by using <rollback
> markRollbackOnly="true"/> I should see no exception when I do the rollback.
> However this is not the case, when I look at the log I see a
> RollbackExchangeException and I don't know why.
>
> org.apache.camel.RuntimeCamelException:
> org.apache.camel.RollbackExchangeException: Intended rollback.
> Exchange[Message: ]
>         at
> org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:1157)[88:org.apache.camel.camel-core:2.8.0.fuse-07-15]
>         at
> org.apache.camel.component.jms.EndpointMessageListener$EndpointMessageListenerAsyncCallback.done(EndpointMessageListener.java:174)[93:org.apache.camel.camel-jms:2.8.0.fuse-07-15]
>         at
> org.apache.camel.component.jms.EndpointMessageListener.onMessage(EndpointMessageListener.java:110)[93:org.apache.camel.camel-jms:2.8.0.fuse-07-15]
>         at
> org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:560)[94:org.springframework.jms:3.0.5.RELEASE]
>         at
> org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:498)[94:org.springframework.jms:3.0.5.RELEASE]
>         at
> org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:467)[94:org.springframework.jms:3.0.5.RELEASE]
>         at
> org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:325)[94:org.springframework.jms:3.0.5.RELEASE]
>         at
> org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:243)[94:org.springframework.jms:3.0.5.RELEASE]
>         at
> org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1058)[94:org.springframework.jms:3.0.5.RELEASE]
>         at
> org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1050)[94:org.springframework.jms:3.0.5.RELEASE]
>         at
> org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:947)[94:org.springframework.jms:3.0.5.RELEASE]
>         at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown
> Source)[:1.7.0_07]
>         at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown
> Source)[:1.7.0_07]
>         at java.lang.Thread.run(Unknown Source)[:1.7.0_07]
>
> Is there something I'm missing between the AMQ transaction and the camel
> route? Any help would be greatly appreciated, thank you.
>
>
>
> --
> View this message in context: http://camel.465427.n5.nabble.com/Odd-AMQ-Transaction-Behavior-tp5737418.html
> Sent from the Camel - Users mailing list archive at Nabble.com.



-- 
Claus Ibsen
-----------------
Red Hat, Inc.
Email: cibsen@redhat.com
Twitter: davsclaus
Blog: http://davsclaus.com
Author of Camel in Action: http://www.manning.com/ibsen