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/
>

Reply via email to