I thought that calling conn.rollback() would sort out the DB side and the thrown SQL exception would sort out the JMS side.
I am clearly missing something rather important here, so I will take your advice and spend some time looking into Spring. On Fri, Feb 20, 2009 at 7:26 PM, Claus Ibsen <claus.ib...@gmail.com> wrote: > 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/ >