Sunday, July 21, 2013

Retry and Rollback using DB adapter - SOA Suite 11G

Hi All,

Retrying and rolling back transactions that got failed while invocation is one of the major things that needs to be keep in mind while designing the solution for any interface.As it helps in preventing any data discrepancy that can be there between source and target systems,had there not been any rollback in case of failed transaction.

I will be demonstrating,how to retry and rollback failed transactions in SOA.To illustrate this use case I will be using one JMS queue from where our composite will consume the message and, after that it will insert data in 3 tables that I have created for this usecase.you will be requiring XA JNDIs both for Database and JMS Adapters.

Three tables have been created namely Customer,Order, and Invoice.Our SOA process will insert records in table in the same order.


On weblogic console,we need to set some properties for our jms queue for retry functionality.Just go to your jms queue and navigate to "Delivery Failure" tab for your queue.Set following parameters
  • Redilvery Delay Override: 10000 (10 seconds) It is the interval after which rolledback messages will be retried.
  • Redilvery Limit: 2 (Number of times failed message will be retried).
  • Expiration Policy: Redirect (or Discard, if you want to discard the message after retry) Redirect will move the message to "Error Destination" if even after configured retry parameters message is failed.
  • Error Destination: <Queue Name> Queue to which failed message will be moved after all retry attempts.
In the BPEL process, add catch or catch all handler for your composite to handle any faults that may occur.In the Catch All block ,explicitly throw a rollback fault using throw activity.It will rollback the complete transaction i.e. undo all the data inserted in any of the tables and then request message will be rolled back to the jms queue.

NOTE: Any fault thrown using throw activity that is not being caught will result in rollback of complete transaction.


Now,first we will test the happy path.Deploy your code to EM and test the interface.Records will be inserted into all the tables successfully.
To see how rollback works,I will intentionally change the DB jndi for Invoice adapter.To do that open jca file for your Invoice DB Adapter and give some random value in that.Save and redeploy the code.Now the interface will fail while inserting the data in Invoice table and flow will got to Catch All block,where transaction will be rollbacked.
To validate this,check the tables and no new records would have been inserted into the tables.

Since we have configured,retry parameters for our request queue, the rollbacked message will be retried again after 10 seconds.Message state will be changed to "delayed" which means it is being retried.

After all failed attempts the message will be redirected into the error destination that we have configured for our queue.


In this way, you can implement retry and rollback functionality in your interfaces.
Hope this helps you.


Happy Learning,
Cheers !!!

13 comments:

  1. Hi,I have the same scenario where I am reading from a JMS queue and writing into DB table but I am getting the error " Caused by java.sql.SQLException: Cannot call Connection.commit in distributed transaction".

    Please help how can I resolve this

    ReplyDelete
    Replies
    1. Can u pls tell wen r u getting this exception ?? while writing into DB or while rolling back in case of failure ??

      Delete
    2. Hi Karan,

      The above eror get resolved.My DS was xa but i was giving it into nonxa DS in DB connection pool.Now my success case is working fine but retry is still not working.I gave wrong jndi for DB but still I can't see the transaction rollback.Once the message is picked from queue, its not going back to the queue.

      Delete
    3. Hi,

      Have u added catch all activity ?? and in case of error, is your flow going into catch all block ?? In the catch all block have u thrwon rollback activity ?? Cross check your jms JNDI it should be XA as well

      Please check and let me know.

      Regards,
      Karan

      Delete
    4. Hi Karan, I have added catch all activity only and my JNDI is also xa.and I have thrown rollback also as you have mentioned.

      Do I need to make sync WSDL for JMS? As of now my all wsdls are async only.

      Delete
    5. It should rollback then....In the flow trace are you able to see transaction rollback message just after throw activity ?? one in the 3rd last screenshot

      I hope all your jndis jms and DB are XA

      Delete

  2. Sep 5, 2013 6:44:09 AM The transaction was rolled back. The work performed for bpel instance "50102" was rolled back, but the audit trail has been saved for this instance.If this is a sync request, please resubmit the request from the client. If it is an async request, please recover from the recovery console by resubmitting the invoke message.
    Fetching Data...

    I am getting this message. I have verified all my jndi and DS ...all are XA only

    ReplyDelete
    Replies
    1. Can you check and confirm whether the data you are inserting into tables, its getting rolledback in case of failure ??

      Delete
  3. No, That is the issue, its not getting rolled back. I am loosing the messages once its picked up from jms.

    ReplyDelete
  4. Send me ur code on my mail id. I will try to figure out the issue.

    ReplyDelete
  5. Thank you Karan. Very helpful blog.

    ReplyDelete
  6. Excellent Karan Mann..All your posts are superb.Lot of useful to me.Thank You so much.

    ReplyDelete