Question

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.

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top