<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>
<channel>
	<title>Comments on: JMS, transactions and exception handling</title>
	<atom:link href="http://www.magpiebrain.com/blog/2005/04/04/jms-transactions-and-exception-handling/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.magpiebrain.com/blog/2005/04/04/jms-transactions-and-exception-handling/</link>
	<description>Sam Newman's blog</description>
	<pubDate>Fri, 21 Nov 2008 22:38:10 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.3</generator>
		<item>
		<title>By: Bill de hOra</title>
		<link>http://www.magpiebrain.com/blog/2005/04/04/jms-transactions-and-exception-handling/#comment-656</link>
		<dc:creator>Bill de hOra</dc:creator>
		<pubDate>Tue, 05 Apr 2005 23:38:18 +0000</pubDate>
		<guid isPermaLink="false">http://www.magpiebrain.com/2005/04/04/jms-transactions-and-exception-handling/#comment-656</guid>
		<description>I kind of agree with James. Except that it's very difficult to abstract JMS provider behaviour away from the logic b'cos the spec is so loose. JMS providers have too much freedom - actually calling JMS a spec is kind of a joke.  Unless you decide to depend on a specific provider's behaviour (ie make activemq/joram/jbossmq part of the architecture) it's really tricky to tee up the SLAs required by the business to the relible behaviours of the provider (case in point: a transaction is not the same as an order fulfilment). Worst case is you will depend on a provider specific behaviour unbeknownst.  

This problem bites as well when it comes to web based messaging (ie teeing up BizTalk exchanges with the business  requirements around duplicates).

So, the last time I worked this kind of system (XML messaging over JMS), we went live and naturally the surprise exceptions came in.  But what was really biting us were the unhappy side effects of either trying to recover inside onMessage() or the JMS provider sending the message back in. For the most we didn't see transient failures at that level; if it didn't go the first time it probably  ain't gonna go period. Web systems are very different in terms of transient failures (retrying is entirely justified).   

So, after a few months I decided to change the onMessage()  failure behaviour to use an an application level DLQ - a file system write. We removed a lot of code. No exceptions ever thrown back to the provider, no smart handling, no recovery behaviour. To heck with commits and rollbacks, just crash out, log the problem, plonk the message on disk, and wait for the next message. As dumb as you like, but with no partial failure. It's unintuitive, but it was a very good way to get a highly robust application that had the required business semantics. What was lost in leveraging JMS infrastructure (after all, who the heck writes a custom DLQ on top of JMS), was gained in transparency. 

</description>
		<content:encoded><![CDATA[<p>I kind of agree with James. Except that it&#8217;s very difficult to abstract JMS provider behaviour away from the logic b&#8217;cos the spec is so loose. JMS providers have too much freedom - actually calling JMS a spec is kind of a joke.  Unless you decide to depend on a specific provider&#8217;s behaviour (<acronym title="Internet Explorer">IE</acronym> make activemq/joram/jbossmq part of the architecture) it&#8217;s really tricky to tee up the SLAs required by the business to the relible behaviours of the provider (case in point: a transaction is not the same as an order fulfilment). Worst case is you will depend on a provider specific behaviour unbeknownst.  </p>
<p>This problem bites as well when it comes to web based messaging (<acronym title="Internet Explorer">IE</acronym> teeing up BizTalk exchanges with the business  requirements around duplicates).</p>
<p>So, the last time I worked this kind of system (<acronym title="eXtensible Markup Language">XML</acronym> messaging over JMS), we went live and naturally the surprise exceptions came in.  But what was really biting us were the unhappy side effects of either trying to recover inside onMessage() or the JMS provider sending the message back in. For the most we didn&#8217;t see transient failures at that level; if it didn&#8217;t go the first time it probably  ain&#8217;t gonna go period. Web systems are very different in terms of transient failures (retrying is entirely justified).   </p>
<p>So, after a few months I decided to change the onMessage()  failure behaviour to use an an application level DLQ - a file system write. We removed a lot of code. No exceptions ever thrown back to the provider, no smart handling, no recovery behaviour. To heck with commits and rollbacks, just crash out, log the problem, plonk the message on disk, and wait for the next message. As dumb as you like, but with no partial failure. It&#8217;s unintuitive, but it was a very good way to get a highly robust application that had the required business semantics. What was lost in leveraging JMS infrastructure (after all, who the heck writes a custom DLQ on top of JMS), was gained in transparency.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: James Strachan</title>
		<link>http://www.magpiebrain.com/blog/2005/04/04/jms-transactions-and-exception-handling/#comment-655</link>
		<dc:creator>James Strachan</dc:creator>
		<pubDate>Tue, 05 Apr 2005 20:12:20 +0000</pubDate>
		<guid isPermaLink="false">http://www.magpiebrain.com/2005/04/04/jms-transactions-and-exception-handling/#comment-655</guid>
		<description>Radu - not really; that just means its up to a JMS provider to decide how to distribute messages across queue receives on the same queue. i.e. how it load balances.

Also note, doing efficient parallel consumption across threads in JMS is harder than it might first appear - quick answer, take a look at ServerSessionPool in JMS.</description>
		<content:encoded><![CDATA[<p>Radu - not really; that just means its up to a JMS provider to decide how to distribute messages across queue receives on the same queue. i.e. how it load balances.</p>
<p>Also note, doing efficient parallel consumption across threads in JMS is harder than it might first appear - quick answer, take a look at ServerSessionPool in JMS.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Radu-Adrian Popescu</title>
		<link>http://www.magpiebrain.com/blog/2005/04/04/jms-transactions-and-exception-handling/#comment-654</link>
		<dc:creator>Radu-Adrian Popescu</dc:creator>
		<pubDate>Tue, 05 Apr 2005 18:51:25 +0000</pubDate>
		<guid isPermaLink="false">http://www.magpiebrain.com/2005/04/04/jms-transactions-and-exception-handling/#comment-654</guid>
		<description>Quote the Javadoc: "Although it is possible to have multiple QueueReceivers for the same queue, the JMS API does not define how messages are distributed between the QueueReceivers."

If I'm not mistaken, this means that most of the benefits claimed by using J2EE containers or Spring for processing producer-consumer style messages is lost - meaning session and whatever polling &#38; thread pool &#38; stuff.

As for topics I think a thread pool is easily written. I see no reason whatsoever to tie myself to a particular framework and philosophy in order to achieve that stuff. 

Come XA, I definitely need a transaction manager...</description>
		<content:encoded><![CDATA[<p>Quote the Javadoc: &#8220;Although it is possible to have multiple QueueReceivers for the same queue, the JMS <acronym title="Application Programming Interface">API</acronym> does not define how messages are distributed between the QueueReceivers.&#8221;</p>
<p>If I&#8217;m not mistaken, this means that most of the benefits claimed by using J2EE containers or Spring for processing producer-consumer style messages is lost - meaning session and whatever polling &amp; thread pool &amp; stuff.</p>
<p>As for topics I think a thread pool is easily written. I see no reason whatsoever to tie myself to a particular framework and philosophy in order to achieve that stuff. </p>
<p>Come XA, I definitely need a transaction manager&#8230;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Sam Newman</title>
		<link>http://www.magpiebrain.com/blog/2005/04/04/jms-transactions-and-exception-handling/#comment-653</link>
		<dc:creator>Sam Newman</dc:creator>
		<pubDate>Tue, 05 Apr 2005 17:25:04 +0000</pubDate>
		<guid isPermaLink="false">http://www.magpiebrain.com/2005/04/04/jms-transactions-and-exception-handling/#comment-653</guid>
		<description>For us, we have a single entry point - this one message handler, so a mini-JMS container is fine - it doesn't really warrant JBoss, Geronimo. I'm still unsure what Spring would give us in this scenario - if we use spring we'd have to configure transaction management anyway, and I'd rather write code (which is easier to test than config files). If/when our transaction management becomes more complicated (we might have to end up implementing two-phase commit or saga transactions) Spring might be a sensible choice.</description>
		<content:encoded><![CDATA[<p>For us, we have a single entry point - this one message handler, so a mini-JMS container is fine - it doesn&#8217;t really warrant JBoss, Geronimo. I&#8217;m still unsure what Spring would give us in this scenario - if we use spring we&#8217;d have to configure transaction management anyway, and I&#8217;d rather write code (which is easier to test than config files). If/when our transaction management becomes more complicated (we might have to end up implementing two-phase commit or saga transactions) Spring might be a sensible choice.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: James Strachan</title>
		<link>http://www.magpiebrain.com/blog/2005/04/04/jms-transactions-and-exception-handling/#comment-652</link>
		<dc:creator>James Strachan</dc:creator>
		<pubDate>Tue, 05 Apr 2005 17:19:05 +0000</pubDate>
		<guid isPermaLink="false">http://www.magpiebrain.com/2005/04/04/jms-transactions-and-exception-handling/#comment-652</guid>
		<description>You can, if you like, write your own JMS consumption code (presumably handling JMS connection pooling &#38; thread pooling?), setting up subscriptions, transaction handling with rollback &#38; retry code - with or without XA - if you like.

But this is exactly what the JMS containers (be it MDB or MDP) do for you.

(Also note that a JMS container will do nice JMS connection, session &#38; thread pooling for you too - not using a regular client side JMS consumer, but using the ServerSessionPool stuff - with a configurable thread pool so you can define how parallel things go &#38; how threads work across multiple subscriptions etc).

This reminds me a bit of Joe's recent post on DAO frameworks. You're effectively writing a mini-JMS container to handle the transactions &#38; retry. This is totally fine (I've done the same before in the past).

However you could try just reuse an MDB / MDP container, which does everything you need - plus lots more (connection pooling, thread pooling, nicer configuration, full XA support if required etc etc)  - without using proprietary APIs.

i.e. there's no reason why you can't do this using JBoss, Geronimo or Spring today. 

The only real trick is - for invalid messages, send to a DLQ, otherwise throw a runtime exception for system failures. Other than that you can reuse the rest - if you wish. But by all means write your own mini-JMS container if you wish - horses for courses etc.

(BTW the links work currently for the ActiveMQ examples on the JCA container :)</description>
		<content:encoded><![CDATA[<p>You can, if you like, write your own JMS consumption code (presumably handling JMS connection pooling &amp; thread pooling?), setting up subscriptions, transaction handling with rollback &amp; retry code - with or without XA - if you like.</p>
<p>But this is exactly what the JMS containers (be it MDB or MDP) do for you.</p>
<p>(Also note that a JMS container will do nice JMS connection, session &amp; thread pooling for you too - not using a regular client side JMS consumer, but using the ServerSessionPool stuff - with a configurable thread pool so you can define how parallel things go &amp; how threads work across multiple subscriptions etc).</p>
<p>This reminds me a bit of Joe&#8217;s recent post on DAO frameworks. You&#8217;re effectively writing a mini-JMS container to handle the transactions &amp; retry. This is totally fine (I&#8217;ve done the same before in the past).</p>
<p>However you could try just reuse an MDB / MDP container, which does everything you need - plus lots more (connection pooling, thread pooling, nicer configuration, full XA support if required etc etc)  - without using proprietary APIs.</p>
<p>i.e. there&#8217;s no reason why you can&#8217;t do this using JBoss, Geronimo or Spring today. </p>
<p>The only real trick is - for invalid messages, send to a DLQ, otherwise throw a runtime exception for system failures. Other than that you can reuse the rest - if you wish. But by all means write your own mini-JMS container if you wish - horses for courses etc.</p>
<p>(<acronym title="By The Way">BTW</acronym> the links work currently for the ActiveMQ examples on the JCA container :)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Sam Newman</title>
		<link>http://www.magpiebrain.com/blog/2005/04/04/jms-transactions-and-exception-handling/#comment-651</link>
		<dc:creator>Sam Newman</dc:creator>
		<pubDate>Tue, 05 Apr 2005 13:46:24 +0000</pubDate>
		<guid isPermaLink="false">http://www.magpiebrain.com/2005/04/04/jms-transactions-and-exception-handling/#comment-651</guid>
		<description>Well, I am keeping the complex (middleware) logic out of the code. What we end up with is a simple MessageListener implementation which just calls process(). Our TransactionalMessageListener delegates calls to our simple listener, and it handles the transactions. In reality, our simple (transactionally unaware) MessageListener processes the message (which in our case involves deserializing XML) and passes the resulting object into a POJO. So we have Transaction Wrapper-&#62;Message Umarshalling-&#62;Processing. 

I'm not sure how using spring would do anything different, apart from perhaps having me code a configuration file rather than write some actual code. Oh, and I'd love to read the ActiveMQ documentation, but it seems all the example links go to your now non-existant CVS repository :-)

And as for keeping transaction management out of business logic, how does that work where transaction management is business logic? For us, we have faliure scenarios which as an implementational detail have been implemented as transactions.</description>
		<content:encoded><![CDATA[<p>Well, I am keeping the complex (middleware) logic out of the code. What we end up with is a simple MessageListener implementation which just calls process(). Our TransactionalMessageListener delegates calls to our simple listener, and it handles the transactions. In reality, our simple (transactionally unaware) MessageListener processes the message (which in our case involves deserializing <acronym title="eXtensible Markup Language">XML</acronym>) and passes the resulting object into a POJO. So we have Transaction Wrapper-&gt;Message Umarshalling-&gt;Processing. </p>
<p>I&#8217;m not sure how using spring would do anything different, apart from perhaps having me code a configuration file rather than write some actual code. Oh, and I&#8217;d love to read the ActiveMQ documentation, but it seems all the example links go to your now non-existant <acronym title="Concurrent Versions System">CVS</acronym> repository :-)</p>
<p>And as for keeping transaction management out of business logic, how does that work where transaction management is business logic? For us, we have faliure scenarios which as an implementational detail have been implemented as transactions.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: James Strachan</title>
		<link>http://www.magpiebrain.com/blog/2005/04/04/jms-transactions-and-exception-handling/#comment-650</link>
		<dc:creator>James Strachan</dc:creator>
		<pubDate>Tue, 05 Apr 2005 13:34:51 +0000</pubDate>
		<guid isPermaLink="false">http://www.magpiebrain.com/2005/04/04/jms-transactions-and-exception-handling/#comment-650</guid>
		<description>How about - just writing MessageListener POJOs with no complex logic; letting any runtime exception thrown bubble up.

Then if you can detect an invalid message in some way, send it to a dead letter queue? Then for bad messages, you process them successfully but place them on a DLQ. For any bad errors, you let runtime exceptions bubble up.

Once you've done that you can use a JMS container (MDB container or a Message Driven POJO container, like the one for Spring) to process the messages and let it worry about handling JMS transactions start/commit/rollback, XA transactions or message acknowledgements, re-try, timeouts and the like?

i.e. keep the middleware stuff out of your business logic &#38; focus on the main logic you need to do - process the messages and detect bad messages.

If you wanna Message Driven POJO container using Spring, try this...

http://activemq.codehaus.org/JCA+Container

Otherwise any old MDB container would do the trick (though you might wanna wrap your MessageListeners's in  MDB wrappers to make them full MDBs).</description>
		<content:encoded><![CDATA[<p>How about - just writing MessageListener POJOs with no complex logic; letting any runtime exception thrown bubble up.</p>
<p>Then if you can detect an invalid message in some way, send it to a dead letter queue? Then for bad messages, you process them successfully but place them on a DLQ. For any bad errors, you let runtime exceptions bubble up.</p>
<p>Once you&#8217;ve done that you can use a JMS container (MDB container or a Message Driven POJO container, like the one for Spring) to process the messages and let it worry about handling JMS transactions start/commit/rollback, XA transactions or message acknowledgements, re-try, timeouts and the like?</p>
<p>i.e. keep the middleware stuff out of your business logic &amp; focus on the main logic you need to do - process the messages and detect bad messages.</p>
<p>If you wanna Message Driven POJO container using Spring, try this&#8230;</p>
<p><a href="http://activemq.codehaus.org/JCA+Container"  rel="nofollow">http://activemq.codehaus.org/JCA+Container</a></p>
<p>Otherwise any old MDB container would do the trick (though you might wanna wrap your MessageListeners&#8217;s in  MDB wrappers to make them full MDBs).</p>
]]></content:encoded>
	</item>
</channel>
</rss>
