Hi Well you gotta get some TX manager in the mix. Otherwise how would you ensure that the JMS and DB participates in the same transaction?
Of couse the Camel JMS consumer will be able to rollback if there is an exception thrown, but that does still not ensure that the JMS and DB are managed in the same TX. So if you are able to store in database, but then sending to the next DB queue fails, then the message will be rolled back to the original JMS queue, but the DB is comitted. So I would advice you to learn a bit on the Spring TX stuff and NOT ROLL OUT YOUR OWN, its. harder than you think. The Spring guys have worked hard on this for many years to get it in that stellar quality it is. On Fri, Feb 20, 2009 at 5:37 PM, Tristan Koen <tristan.k...@gmail.com> wrote: > I think I am starting to get the hang of Camel now. I have, however, run > into one more problem that I would like some advice on. > > I have already read through the "Transactional Client" documentation page > before anyone asks. More on that later :) > > My scenario is very simple. I have the following (simplified) route: > from(jms:queue:A).process(new DBLogger()).process(new > DBMessageFilter()).to(jms:queue:B) > > I receive a message and log its contents to a database. I then pass it > through to a filter that extracts very specific bits of information from the > message body. Finally, the modified message is added to another queue. > The problem I have is that an error (such as a SQLException) could occur in > DBMessageFilter(). If such an error occurs, I would want to roll-back the > insert performed by DBLogger(). > > The way I see it, I have one of four options: > 1. Use the Spring PlatformTransactionManager > I would rather avoid this, because I am not (at all) familiar with the > Spring Framework and would rather not code things I can't support properly. > > 2. Combine DBLogger and DBMessageFilter into a single class > I don't want to do this, since I am looking at a general solution that I can > use on a number of different routes. > > 3. Put an intermediate queue between DBLogger() and DBMessageFilter() > This would be an enormous waste of resources and could also become very > cumbersome as the number of routes grow. > > 4) Use DelegateProcessors. This is my favoured solution and the one I would > like some comment on. > > Modify my route lo look like: > from(jms:queue:A).intercept(new DBLogger()).process(new > DBMessageFilter()).to(jms:queue:B) > > My DBLogger class would look something like this: > public class DBLogger extends DelegateProcessor > { > public void process(Exchange exchange) throws Exception { > // Connection conn = .... > // conn.setAutoCommit(false); > // Log message content > try { > processNext(exchange); > catch (SQLException ex) { > conn.rollback(); > throw ex; // for the benefit of the Routemap > finally { > conn.commit(); > } > } > > Is this a valid approach, or does it have some major flaw that I am missing? > Otherwise, is there a better (non-spring) way to do this. > > I recognise that at some point in the not-too-distant future, I am going to > have to look at the Spring Framework, but I just don't have the time at > present :( > -- Claus Ibsen Apache Camel Committer Open Source Integration: http://fusesource.com Blog: http://davsclaus.blogspot.com/