Hi Tom,

> In our application we have a lot of routes that follow the same pattern:
> read a message, do some processing, update/insert in the database and then
> send a message to the next route.
> (...)
> do we need XA transactions (...) ?

That's right. You don't need XA to transactionally process your
message flow. Plain local JMS transaction, ActiveMQ reredelivery
mechanism and some Camel magic will be fine here. :)

Just mark consumer endpoint as transactional [1] (as demonstrated on
the snippet below) and ActiveMQ will handle the message redelivery for
you.

<from uri="activemq:div.line"/>
<transacted/>
<bean ref="divServiceActivator" method="validateDivLine"/>

Keep in mind that ActiveMQ broker will keep the message in div.line
queue until the transaction will be committed by the Camel at the end
of the route (after sending message to div.line.processed queue). If
divServiceActivator will throw the exception during the DB update, the
Camel will not commit and message incoming from div.line will be
redelivered by the broker. You can control how many times message will
be redelivered by the broker on the ActiveMQ configuration level [2].

Now is the tricky part. Notice that it is still possible that Camel
can fail to commit JMS transaction *after* successful DB update (power
outages happen). That would mean that incoming message will be
redelivered and processed twice. To handle this situation and keep
your system state concise make divServiceActivator#persistDivVehicle()
bean invocation idempotent [3], so it won't try to alter database
twice. You can also try to make
divServiceActivator#persistDivVehicle() operation idempotent on the
business logic level (sometimes it is as trivial as checking if entity
with given ID hasn't been persisted already).

Cheers.

[1] http://camel.apache.org/transactional-client.html
[2] http://activemq.apache.org/message-redelivery-and-dlq-handling.html
[3] http://camel.apache.org/idempotent-consumer.html

-- 
Henryk Konsek
http://henryk-konsek.blogspot.com

Reply via email to