Last week I had a great OSB BlackBelt training of Samrat Ray and organized by the SOA Community In this training we talked a lot about Global Transactions ( XA), QoS ( Quality of Service ) in combination with Transports and JCA Adapters. Because this is so important ( you dont want to lose a Message ) I decide to make a blog about this subject and I will explain the different scenarios options you have in the Oracle Service Bus.
Before I can start I need to create and configure some Queues. In this blogpost I will use JMS for the Proxy and the Business service but you can also use EJB, MQ or the Direct Binding ( SOA Suite 11g ) for the Business Service, they all support XA, HTTP transport does not support XA ).
First create the RequestQ Queue combined with an ErrorQ Queue ( Now failed messages will be redirected to this Queue and won't be lost in Space), a ReponseQ Queue and a DestinationQ Queue ( used in the Business service )
Here is a picture how you can define an Error Queue on the RequestQ. Go to the Queue, select the Delivery Failure Tab in the Configuration Tab. Now you can set the Redirect Expiration Policy and select the Error destinations.
I start with a simple scenario. Add a message in the RequestQ and we will expect the message in the ResponseQ.
Add a Proxy Service ( any XML) and select JMS as protocol. OSB generates a default url with an internal XA connection factory and add the Queue name to this URL.
Leave the Message Flow empty and a message in the RequestQ ( Go to the Queue, monitoring tab and a create a new message). Always change the Redelivery Limit ( Don't use the value -1 )
So far so good, now let's raise an Error on the Response Channel and take a look at the results. In the message flow I added a PipelinePair with a stage and an Error activity.
Add a message to the RequestQ, ( set the Redelivery to 2 else you will get a loop ) what you will see that the message now is added to the ErrorQ and not to the ResponseQ. This is good behaviour. Now you can re-process this message again by moving it to the RequestQ or let an ErrorHospital handle it.
The next step is adding a business service ( also use JMS and a XA Connection Factory ) and make this part of the Global Transaction. Add a routing to this Business Service in the message flow of the Proxy Service. This will also add the message to the DestinationQ. Make sure that the Message Type = text ( for this test only )
When you disable the option Same Transaction for Response ( Default behavior ) then this message will be removed even when there is an error in the Response Channel of the Proxy Service.
The last part of this blog is taking a look at Quality of Service ( QoS ). QoS requires a transaction ( The Proxy Service need to start it ) and you can control, if the Business Service will take part on the Global Transaction. You need to add a Routing options activity to the request part of the Routing Node. First set QoS on Best Effort. Exactly Once is the default value when you use JMS and XA in the Proxy Service.
Conclusion: You need to think about your process and ask yourself is it a problem when your message is lost and what about when you deliver the same message again and again. Be aware one transaction for the request and response in the Proxy Service is not enabled by default and you need to configure it and test all the situations. Off course you need to use XA connection factories, Datasources and XA configured Resource Adapters.
HTTP Proxy or Business Services won't be part of XA. When you call a BPEL service you can use the Direct Binding transport for this.