Transactions, delivery guaranties, state

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Transactions, delivery guaranties, state

Максим Самарин
Hello all,

I'm learning Apache Camel and several questions appeared regarding transactions and delivery guaranties.
Could you help with them please.


1) Route Ex.:

from ( "jms:queue:inputQueue" )
    . split ( splitter )
.... any other transformations
    . to ( "jms:queue:outputQueue" ) ;

I.e. there is input JMS queue, from which messages are taken, than each message is spllitted on several (possibly other transformations) and all are sent to output queue. I.e. 1 input message is transformed to multiple in output queue.

Is my understanding correct, that if both queues are configured to use transactions, whole route will be done in one transaction. And so message from "inputQueue" will be removed only after all messages are successfully written to "outputQueue"?
And accordingly(1 input message is spllited on 10), if several messages are successfully written to output queue, but procession of one failed(6 correctly processed, but 7th failed) - input message will be left in "inputQueue" and no new messages will be added to "outputQueue" (i.e. all 6 successful will be removed). Is that correct?
So one transaction for removing message from input queue and writing several to output queue, Correct?



2) Example with database and file

1. Read file
--  start xa tx
2.1. Split file
2.2. Send parts to JMS
2.3. Write record to DB (file processed + number of parts + other metadata)
-- commit/rollback xa tx

3. Other steps, which will be able to retrieve data from db, to get info about file and its metadata.
There might be another steps which also will be able to update this record with their own data.
So in general, db will be used as persistent storage of each procession state.


As I understood, that's possible to do with </transacted>. i.e. like

from("file:")
   .transacted()
   .split()
   .beanRef("dbRepo", "writeToDb")
   .to("jms:queue")

so transaction will be started right before split and will be committed after placing into the queue.
I.e. split, write to db and write to queue will be in one tx, and if anything fails, everything will be rolledback - no new records in db, no messages in queue.
Is that correct and is such behavior possbile?
But to work that properly, platform transaction manager and transaction manager must be configured correctly to support XA transactions.
And is that a good idea, to store state of procession? Or is that better to be stateless and just build idempotent consumers(to not to process same message twice). But to do that, info about what was processed still need to be stored somewhere (db, kafka, etc), so looks like just changing the storage.

Appreciate any input.
Thanks in advance!


--
Maxim