Using Transactions with JMS (ActiveMQ)

There are several services in our backend that send and receive messages through JMS with Apache ActiveMQ. Each service has one session for the ActiveMQ broker. Now we want to do the following (pseudo-code):

Service s1:

Message m = createMessage("s2","Hello World") sendMessage(m) try { Message answer = commit() ... } catch (TransactionFailedException e){ ... } 

Service s2:

 onMessageReceive: try { Message m = getReceivedMessage() Message answer = doSomeStuff() send(answer) } (Exception e) { rollback() } 

A required transaction must be blocked until a response is received or the transaction is completed. It should also be possible for the s2 service to create a new nested transaction because s2 is sending a message to another service. How can I use transactions from ActiveMQ to achieve this behavior? There are a few examples, but in these examples, transactions are simply used as a batch mechanism for sending messages.

+4
source share
1 answer

I am interpreting your question to mean that you want a failure in s2 to roll back the current transaction in s1.

So you want

 s1 do some work s2 do some work if ( s2 OK ) perhaps do even more work in s1 commit s1 else rollback s1 

The JMS asynchronous model is not classically designed for this purpose. The main reason is that

  • During transactions, resources (for example, database records) are locked - s1 did some work until the transaction decided that these resources should be locked.
  • Asynch processing is designed to decouple the work of s2 from the work of s1, the work of s2 can occur for many minutes or even several days after the request has been queued. S2 can't know, s1 is still waiting for it. The whole point of JMS design is to separate processing in s1 and s2.

There are two approaches to achieving coordination between s1 and s2:

One of them is to use true distributed transactions using a protocol other than JMS, for example, EJBs can distribute transactions from one process to another or use WS-AtomicTransaction and web services. This adds operational complexity - you need to manage transaction logs and scripts where you have a long-term failure of one component.

An alternative is the development of two interacting systems for reliable processing of "compensating" work. You agree that, for example, s2 may fail, and have secondary processing to handle repeated requests regarding timeouts, etc. In the end, you can move on to situations in which people need to participate, but with a good design, these situations can be minimal. In large-scale systems, there is often no alternative to this, for example, the airline reservation system and the hotel reservation system on the network cannot be developed to coordinate distributed transactions, therefore there is no alternative to thorough processing to reserve flights and rooms.

+2
source

Source: https://habr.com/ru/post/1397385/


All Articles