2

I was wondering if I can get some ideas on how to handle a design issue I'm facing. For simplicity sake, let's say I have 3 endpoints running on 3 different machines/jvms on Tomcat. The endpoints have the following responsibilities:

Endpoint 1 - takes in demand data and transforms this data into order requests

Endpoint 2 - takes in order requests, saves the order, and returns an order

Endpoint 3 - takes in an order, formats into a vendor specific xml, and sends it to a queue.

Edit: These endpoints exist as current services to other clients via REST. I have the option of using Atomikos for a JTA Transaction Manager and we are using ActiveMQ.

With that being said, I have a queue setup that receives demand data messages. For each received demand data message, I essentially want to funnel them through each of the 3 end points in one unit of work via XA. I have complete control of each of the 3 endpoints so I have some flexibility in terms of what communication protocols they can use. Also, there will eventually be around 500k to 1 million of these messages coming in on a daily basis. What communication protocol would you guys use to tie these endpoints together in a distributed transaction?

I have some experience with Camel, but I'm getting stomped on how to tie them together in one unit of work. Would RMI be more appropriate than JMS since this seems synchronous in nature? Thanks ahead of time for any help that's provided.

kdye43
  • 25
  • 1
  • 5
  • How long would these transactions need to run? And how often will they need to be rolled back? – flup Mar 26 '13 at 23:23
  • From my point of view it makes no sense to say on one hand, I want to decouple things and take an asynchronous approach for thins reason and on the other hand I want to couple them higly by saying step 1 is only successful if step 3 is successful. And you should be aware that long running transactions hurt throughput of such a system. So to your last question: YES, a synchronous protocol like RMI or WebServices with a single controler will ease your job and help to keep the tranctions short as they are synchrinzed well. – Bernd Ebertz Mar 27 '13 at 08:24
  • @Sir RotN, Thanks for the reply and ideas. Even though I'm trying to group these endpoints together into one transaction, these endpoints currently exist as services to other clients. They have REST service interfaces that UIs can use. – kdye43 Mar 27 '13 at 11:50
  • @flup Thanks for the quick reply. The transactions need run no more than 5 minutes, although each of the processes individually shouldn't take more than a few secs to complete. These transactions will only need to be rolled back for issues like the db not being available or the full flow can't complete within the 5 minutes. Overall, the hope would be less than 1% needs to rollback on a daily basis. – kdye43 Mar 27 '13 at 12:03
  • So great. REST services are meanwhile the most import group of 'WebServices'. So you just have to make them support the XA transaction id and (if not already done) json or xml as result. Then write a controler that opens the transaction, fires the three REST calls and commits. Sounds simple. – Bernd Ebertz Mar 27 '13 at 12:24
  • @SirRotN I wasn't aware that you could do XA via Rest Services. Have you done this before? Any examples? – kdye43 Mar 27 '13 at 13:12
  • Why the breakoff point of 5 minutes? Is someone waiting for a response to the demand data message? And what's going to be the matter in those less-than-1% of the cases? Invalid input? Unable to comply with the order? – flup Mar 27 '13 at 13:33
  • @flup The 5 minute SLA is just business requirement for the process and if it's violated, a notification needs to be sent out. The 1% is more so for the db being down. The percentage could be about 5% for invalid input or validations not being met. – kdye43 Mar 27 '13 at 15:02
  • In fact I never did XA with several client processes, but only with several databases. I expected you to have a solution, as I don't know how RMI or JMS could help you with this. Only real EJB remote calls might do the job out of the box. – Bernd Ebertz Mar 27 '13 at 17:28

1 Answers1

2

From the Apache Camel documentation at fusesource:

Distributed transactions A distributed transaction refers to a transaction in a distributed system, where the transaction scope spans multiple network nodes. A basic prerequisite for supporting distributed transactions is a network protocol that supports transmission of transaction contexts in a canonical format (see also, Distributed transaction managers). Distributed transaction lie outside the scope of Apache Camel transactions.

Distributed transaction managers Usually, a server connects directly to the resources involved in a transaction. In a distributed system, however, it is occasionally necessary to connect to resources that are exposed only indirectly, through a Web service or through a CORBA IDL interface. In this case, you require a TP monitor that is capable of supporting distributed transactions. Several standards are available that describe how to support transactions for various distributed protocols—for example, the WS-AtomicTransactions specification for Web services and the CORBA Object Transaction Service (OTS) specification for CORBA applications.

So no wonder you are getting stomped. Apache Camel does not cover your use case.

I think you can go two ways:

  1. Big Distributed transaction
  2. Coordinated smaller transactions with compensating actions

JTA in tomcat JTA is a global transaction manager. You probably need this in both solutions. (Though with some clever fiddling you might just manage without if you go for option number two.) Tomcat cannot run JTA transactions, but with the help of a transactionmanager it can. See Atomikos vs JOTM vs Bitronix vs?. Adding a Spring JtaTransactionManager will help make this easier to configure. Not all JMS implementations support JTA / are XA resources. You'd have to check if yours does.

Distributed transaction The duration of your transactions is not extremely long, but you'll nonetheless be keeping resources locked for quite a while, and you have many transactions. Performance will get hurt.

JTA is built upon JTS and OTS. A JTA server ought to be able to coordinate transactions with other JTA servers through OTS. This is not trivial to set up, to begin with you have to find an implementation that supports it. And then you have to figure out how to get it up and running.

At a higher level you have WS-Transactions and WS-Coordination. See the metro guide.

Compensating actions Transaction in SOA suggests that it may be better to use a set of coordinated smaller transactions that do not get rolled back, but for which compensating actions can be taken to clean up the mess that occurs when steps fail.

Sending a notification upon timeout would be one such action. Cancelling the order request you've made in endpoint one if you find out that the order requests cannot be fulfilled could be another compensating action.

If you can go this way at all, I'd take it.

Community
  • 1
  • 1
flup
  • 26,937
  • 7
  • 52
  • 74
  • I am not sure if I dare call this an answer, but at the very least it's bigger than a comment so here goes. I realise that your real question is how to set up a distributed transaction manager this does not answer that. I do hope it's refining the question and offering an alternative way to go. – flup Mar 27 '13 at 22:04
  • Thanks for the very detailed answer. I neglected to mention that I did try leveraging Atomikos as the JTA Transaction Manager with Camel. Please except my apologies. I've updated the question to reflect this. In terms of compensating transactions, the issue I have with that approach is what is someone acts on a change you make to the data and right after you roll it back. Or what if you sent a jms message some and the next step in the process causes an error? How would you undo the jms message. With that being said, I'd probably have to use WS or CORBA right? – kdye43 Mar 27 '13 at 22:17
  • Well, take endpoint two. You create an order in a database. You move on. Later in the process you find out the order should not be processed because the customer does not have enough credit. You cannot rollback the order, cause you have no transaction open. But you can cancel it instead. If others have already acted upon it, they too cancel their actions. If this is no good, happens too often and is too costly, create the order as an order reservation. When you are ready to commit, make another call to endpoint two. This time to confirm the reservation. – flup Mar 28 '13 at 00:15
  • Thanks for the help flup. I'd upvote, but I don't have a high enough reputation. – kdye43 Mar 29 '13 at 13:53