Search code examples
apache-camelspring-transactionsspring-camel

Jms component transacted and camel route transacted


After going through Camel In Action book, I encountered following doubts.

I have below 2 routes

A.
from("file:/home/src") //(A.1) .transacted("required") //(A.2) .bean("dbReader", "readFromDB()") //(A.3) only read from DB .bean("dbReader", "readFromDB()") //(A.4) only read from DB .to("jms:queue:DEST_QUEUE") //(A.5)

Questions:
A.a. Is transacted in (A.2) really required here ?

A.b. If answer to #a is yes, then what should be the associated transaction manager of the "required" policy ? Should it be JmsTransactionManager or JpaTransactionManager ?

A.c. As DEST_QUEUE is at the producer end, so does JMS component in (A.5) need to be transacted ?

B. from("jms:queue:SRC_QUEUE") //(B.1) transactional jms endpoint .transacted("required") //(B.2) .bean("someBean", "someMethod()") //(B.3) simple arithmetic computation .to("jms1:queue:DEST_QUEUE") //(B.4)

SRC_QUEUE and DEST_QUEUE are queues of different jms broker

Questions:

B.a. The JMS component in (B.1) is marked as transacted, so in this case does route need to be transacted as mentioned in (B.2) ?

B.b. As DEST_QUEUE is at the producer end, so does JMS component in (B.4) need to be transacted ?


Solution

  • Very good questions to talk about Camel transaction handling.

    General remark: when talking about Camel transactions it means to consume transacted from a transaction capable system like a database or JMS broker. The transacted statement in a route must immediately follow the from statement because it is always related to the consumption.

    A.a. Is transacted in (A.2) really required here ?

    No, it is not. Since the filesystem is not transaction capable, it can't be of any help in this route.

    A.b. If answer to #a is yes, then ... ?

    There is no "filesystem transaction manager"

    A.c. As DEST_QUEUE is at the producer end, so does JMS component in (A.5) need to be transacted ?

    Not sure, but I don't think so. The producer tries to hand over a message to the broker. Transactions are used to enable a rollback, but if the broker has not received the data, what could a rollback do?

    B.a. The JMS component in (B.1) is marked as transacted, so in this case does route need to be transacted as mentioned in (B.2) ?

    It depends because SRC and DEST are on different brokers.

    • If you want an end-to-end-transaction between the brokers, you need to use an XA-transaction manager and then you have to mark the route as transacted.
    • If you are OK with consumer transaction, you can configure the JMS component for it and omit the Spring Tx manager and the Camel transacted statement.

    To clarify the last point: if you consume with local broker transaction, Camel does not commit the message until the route is successfully processed. So if any error occurs, a rollback would happen and the message would be redelivered.

    In most cases this is totally OK, however, what still could happen with two different brokers is that the route is successfully processed, the message is delivered to DEST broker but Camel is no more able to commit against SRC broker. Then a redelivery occurs, the route is processed one more time and the message is delivered multiple times to DEST broker.

    In my opinion the complexity of XA transactions is harder to handle than the very rare edge cases with local broker transactions. But this is a very subjective opinion and perhaps also depends on the context or data you are working with.

    And important to note: if SRC and DEST broker are the same, local broker transactions are 100% sufficient! Absolutely no need for Spring Tx manager and Camel transacted.

    B.b. As DEST_QUEUE is at the producer end, so does JMS component in (B.4) need to be transacted ?

    Same as answer to B.a.