In our backend there are several services that send and receive messages via JMS with Apache ActiveMQ. Each service has a single session to the ActiveMQ broker. We now 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()
}
The commit obviuosly has to block until the answer arrives or the transaction failes. It should also be possible that service s2 creates a new nested transaction because s2 is sending a message to another service. How can transactions from ActiveMQ be used to achieve this behaviour? There are some examples available but in these examples transactions are merely used as a batch mechanism to send messages.
I'm interpreting you question to mean that you want a failure of work in s2 to cause an ongoing transaction in s1 to be rolled back.
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 asynchronous model of JMS is not classically designed for this purpose. The fundamental reason is because
There are two approaches to achieving coordination between s1 and s2:
One is to use true distributed transactions, using a protocol other than JMS, for example EJBs can propagate transactions from one process to another, or use WS-AtomicTransaction and web Services. This does add operational complexity - you have to manange transaction logs and scenarios where you have a long-term failure of one component.
The alternative is to design the two cooperating systems to robustly handle "compensating" work. You accept that, for example s2 may fail, and have secondary processing to deal with resending requests, dealing with timeouts etc. In the end you may come down to some situations where humans need to be involved, but with good design these situations can be minimal. In large scale systems there's often no alternative to this, for example an airline's booking system and a hotel chain's booking system may well not be designed for distributed transaction coordination so there's no alternative to having some careful processing to manage reserving flights and rooms.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With