Transaction handling within OSB

I have seen many OSB newbies getting confused about the transaction handling capabilities in  OSB. This is because transaction enlisting and demarcations are implicit in OSB. This means OSB developer have no explicit actions to start/commit/rollback transactions. However it is possible to influence transaction via code. Lets explain this with JMS transport as example as it will be used as the de-facto transactional transport in asynchronous interfaces.

Enabling Transactions
1. Make sure the source JMS transport URI is using an XA enabled Connection Factory.

2. In Proxy Service Configuration –> JMS Transport –> Advanced Settings –> Check Is XA Required

3. In Proxy Service Configuration –>Message Handling Configuration –>Check Transaction Required.

This will instruct the underlying OSB JMS Transport to start a transaction before executing the proxy service code. The transaction will be committed/rolled back based on how the proxy service code executes.

Committing transaction on non-recoverable exception
1. Transaction will commit implicitly if proxy service code executes successfully.
2. In case of error and if proxy flow enters an error handler , the transaction can still be committed by using a reply action ( “Reply With Success” or “Reply with Failure”)

It can look contradicting that a reply with failure action can in fact commit a transaction, but that’s how it works!
Request Transaction Manager to rollback the transaction
A transaction can be marked to be rolled back by the transaction manager by allowing an error to propagate all the way up to the system error handler.

OSB’s error pipeline can consist of either of the following sequence :

  • Route Error Handler –> Service Error Handler –> System Error Handler (Comes into picture when an error occurs in a route node)
  • Stage Error Handler –> Pipeline (request or response) Error Handler –> Service Error Handler –> System Error Handler (Comes into picture when an error occurs in a stage).

If a particular error handler is not present the error is propagated to the next available parent in the chain until it reaches system error handler. This propagation can be stopped by using a ‘reply’ action in any of the error handlers. The developer can mark a transaction to rollback by allowing an error to propagate all the way to the system error handler by NOT configuring a reply action in any of the intermediate error handlers.

Enlist the target business service within the same transaction
1. The target business service to which the message is routed (using Route Node) or published (using Publish Action) can be enlisted within the same transaction. For this the business service endpoint should be transactional i.e. if JMS should use a XA enabled connection factory.
2. Within the route node or publish action request action, set Quality of Service to “Exactly-Once” using a routing options action.

If the outbound transport is HTTP, there will be a design decision you will need to make on what type of errors to be marked for rollback. OSB’s HTTP transport commits all transaction if it gets a HTTP response code back from the server. So even if it gets a 404 Page Not Found or 500 Internal Server Error , HTTP transport doesn’t mark the transaction for rollback. This will result in message loss if the target service is frontended by webservers. You will get a http error back from the webserver even if the backend app servers hosting the service is down. The transaction then gets committed as HTTP transport didn’t mark it for rollback.

On the other end if you are sending a faulty message and service keeps on returning a soap:Fault which will be returned with a HTTP response code of 500, this will be non retriable fault and you would want to commit the transaction after publishing to an error destination. As noted before this is a designer decision to be taken depending upon your error handling requirements.

To override the default behaviour and make the HTTP transport commit the transaction only on receiving a success response from server ( HTTP response code 200 or 202) , make sure you check the ‘Same Transaction for Response’ checkbox.

That’s all for now..

Advertisements

About atheek

I am a Weblogic consultant working in Middleware/Integration area.
Gallery | This entry was posted in OSB, Transaction and tagged , . Bookmark the permalink.

23 Responses to Transaction handling within OSB

  1. sandeep says:

    how to capture system error handler in a message pipeline?

  2. Prabu says:

    A nice article on transaction handling in OSB. I was baffled by a HTTP 500 internal server error in OSB which blocked me to rollback message in JMS Queue. Finally this article has given me a clear picture of what has to be done. Kudos… Great work man.. Keep your good work

  3. Vho says:

    Hi,

    Thanks for your explanation. Very good article.

    In the section of enabling transaction, if I have XA enabled Connection Factory set, Check Transaction Required but NOT enabling the “Check Is XA Required”. Do you mean the proxy service still not having the XA enabled even the connection factory is XA enabled ? Could you explain ? Thanks

  4. Pingback: Interview with a global client. « rangarb

  5. Dodd Pfeffer says:

    I keep coming back to this article over and over as we develop our pattern for developing OSB services where transactions are required and messaging must be reliable. Great job. Each time I read it, I get more out of it. There is no other source that I have found that provides this information so clearly.

  6. Kania says:

    Hello Atheek

    Thanks for the great post.
    We are having a similar requirement where we need to handle endpoint failures. We are considering JMS queues as mentioned above by you. We need to process the messages in the same order as they were populated in the queue i.e. the first message in the queue is picked by the JMS proxy and routed to the provider service; once this service invocation is success, the second message from the queue should be picked up and so on….. more than 1 message should not be processed at the same time and sent to the provider service…
    Could you please suggest the best possible way to approach this use case.

    Thanks
    Kania

    • atheek says:

      If you are having a single server environment you can set up a work manager with a max thread constraint of 1 and associate it to the dispatch policy of the jms proxy.. this will ensure that only 1 thread will pick the message of the queue at any time and hence can achieve ordering..
      If you are having a clustered environment then you can leverage a weblogic jms feature
      called Unit of Order (UOO)..this is a jms header which needs to be populated by the producer when putting the message to the queue. weblogic jms will ensure that the messages having same UOO will be delivered to the consumer threads in order.. UOO is also a great feature to leverage if you want ordering across only a subset of messages
      and not across all.. e.g. all messages related to flight QF 123 on 01-Sep-2012 should come in order, but no need for ordering of messages for different flights.. UOO allows parallel processing across different subsets while maintaining the sequential ordering
      within the same subset…

      • Kania says:

        Hello Atheek

        Thanks for your reply. We have a clustered env. I will look into UOO and check it out. Regarding the queues; do we need to take care abt deployment of the queues? ie, shld the queues be deployed in a single node or the target can be the cluster?

        Thanks
        Kania

      • atheek says:

        yes you should take care about deployment of queues.. you can look at my post on creating wls resources including jms modules via wlst scripting: https://atheek.wordpress.com/2012/02/28/wlst-modular-scripts-to-createdestroy-wls-resources/

        Queues as such can be targeted to only a single jms server, but weblogic has a concept of Distributed Destinations which allows you to create queue members uniformly across different nodes in a cluster.. pls refer to oracle documentation on jms

  7. sampath says:

    Hi can u provide clear steps to dequeue a message .

    thanks,
    sampath

  8. Neeraj says:

    Hi Atheek,

    Thanks for the post . I have one question :

    We have many asynchronous services in our project which uses jms queues . Whenever the target is unavailable and retry limit is over the message is sent to Error queue which has been configured in the Delivery Failure tab of a jms queue .

    Can you let me know how to pick message from this error queue after a specified time interval of 2 hours and send back to normal queue for further processing .

    Regards,
    Neeraj

  9. Neeraj says:

    Hi Atheek,

    Adding one more question to my above problem :

    If I enable a transaction in my proxy service then in case of target system down , message will be rolled back to my normal queue only .

    But the proxy service associated with the normal queue will again retry it at the same time , forming a loop until the target system comes up which will lead to a high performance issue .

    So , is there any solution in this case also to retry after a specified time interval from normal queue itself when the message is rolled back .

    Regards,
    Neeraj

  10. Jinesh says:

    Hello Atheek,

    I would like to get your advise on the scenario that I am facing.

    We have a message coming from the upstream system which has a start sequence and end sequence along with a payload that we need to modify and send to MQ.
    So if the startSeq = 1 and endSeq = 100, then first we hit the DB and get the data from the DB table that has a Sequence column. So in this case it will fetch 100 records from 1 to 100. Now we need to iterate and update the payload for each record that we received from the database and place the updated payload (one by one in the MQ). So in this case, we need to place 100 updated message in MQ. We need this to be all or none. If there was any error, none of the messages should be consumed by another application that is listening to this queue. We know that MQ Transport is non-XA and we dont want to use JMS transport. Is there a way we can achieve this scenario with MQ transport?

  11. sagnik sarkar says:

    I’ve constructed a flow where proxy service is built in MQ transport and business services is built in MQ/JMS/HTTP transport. I’m routing the message to different Business Service depending on the content of the Request Message. In this scenario how can I ensure At Least Once delivery in OSB. If at least once is not supported then how can I ensure guaranteed delivery of message.

    Does MQ Transport supports XA Transaction. If not then How to achieve this in case of MQ Transport.

    Need your expert opinion urgently. Please help.

    Thanks & Regards
    Sagnik Sarkar

  12. vijay says:

    I just say, Bunch of thanks for your article

  13. Pingback: OSB bookmarks | Oracle SOA and Service Bus

  14. Pingback: Fix Mdb Error Handling Exception Queue Windows XP, Vista, 7, 8 [Solved]

  15. Sandeep says:

    Hi,I have a service which is atomic transaction, So when we are invoking atomic transactional service over proxy service, we are getting the error “Transaction context is required”, As for same we added policy file of AT in business and proxy service but again we are getting same error.
    please help me

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s