Showing posts with label JMS transport. Show all posts
Showing posts with label JMS transport. Show all posts

Friday, June 14, 2013

Understanding Transaction handling within OSB

Understanding Transaction handling within OSB

In this post I will explain how transactions are handled within OSB. Transactions are implicitly marked, in OSB developer there are no EXPLICIT actions to commit/rollback the transaction. However you can influence boundaries/commit/rollback transactions in your process flow.

To explain this, i would use an example which uses JMS transport.

Example flow,

Inbound JMS Q → OSB Proxy service (pick message)- > Business service (push message) → Outbound JMS Q

Few parameter configurations that should be understood before moving forward.

“Same transaction For Response” Check box: 
 
Request pipeline in proxy service is executed in one thread and the response pipeline is executed in another thread. If this config parameter is unchecked, request and response will be executed in different threads(as expected). In this case, when errors occur in the request/response pipeline will not affect the other pipeline.
If it is checked then both request/response pipelines will be executed in the same thread. So, any errors raised in the entire process should be caught & handled else transaction will be rolledback if  there are no error handlers.
This setting can be found in proxy service's->Message handling configuration page. 

 


 “QOS”(Quality of service):

ExactlyOnce – the callee will participate in the same transaction as the caller.
Best Effort – the callee will not participate in the caller transaction and executes in its own transaction context.

With respect to JMS transport,
QOS is set to 'ExactlyOnce' by default in Routing action. (you can use routing options to change it)
QOS is set to 'BestEffort' by default in Publish action. (you can change this is 'qos' parameter in outbound variable)

 
“is XA enabled” – should be checked. In Proxy service->JMS Transport's(Advanced Setting)

XA Connection factory should be used to make connections to endpoints, in our example it is going to be JMS. It is Transaction manager's responsibility to maintain a global transaction and co-ordinate with all XA enabled endpoints in the flow. Transaction manager will let end systems know whether it has to commit or rollback the transaction. Any XA enabled CF's can participate in global transaction. (ex: JMS, DB)

In non-XA CF's there is no central co-ordinator to maintain global transaction. If non- XA CF's used then it is left to the end systems to either commit/rollback and it cannot participate in global transaction, so if any error happens in the process flow, non-XA transaction will be independent of process flow. From within the process flow you cannot influence to commit/rollback.

Note:- It is very important to use XA-Connection Factories.

Let us move one more step further.

In what scenarios a transaction will be committed in OSB.

  1. Transaction will be commited if proxy service executes successfully without any errors.
  2. In case of error, in error handler you can add reply action to commit the transaction.
    (both “Reply with Success” and “Reply with Failure”)
In what scenarios a transaction will be rolled back in OSB.
  1. A transaction is marked to be rolled back by the transaction manager if the error is allowed to propagate all the way up till system error handler. If error handlers are not defined in the process, errors will be propagated to the highest level(system error handler), this makes the transaction manager to mark the transaction to be rolled back. However, as said earlier, error propagation can be stopped by using reply action.

Test Cases that I performed to test the transactions scenarios which I explained above:

Process flow,

Inbound JMS Q → OSB Proxy service (pick message)- > Business service (push message) → Outbound JMS Q

Note:
Queues – InQ, OutQ and ErrorQ
In proxy service I added “Raise Error” action purposely to raise an exception in either request/response pipeline.
Business service to push message can be invoked either using publish or Routing action.
 
TC1: Success case - 

Required Configuration:
  1. 'Same Transaction For Response' – 'Checked/Unchecked'(doesn't matter).
  2. Raise Error Action: Not Used in the flow.
Result:
  1. Proxy picks up the message from InQ and places it in OutQ
  2. Message in InQ is deleted.
Observation: As expected transaction is committed

 
TC2: Error Case – Raise an error in request pipeline

Required Configuration:
  1. 'Same Transaction For Response' – 'Checked/Unchecked'.
  2. Raise Error Action: Place it request pipeline after invoking business service to push message.
  3. Test this scenario with setting QOS to BestEffort and Exactly Once.
Result:
  1. Proxy picks up the message from InQ and pushes it to OutQ
  2. Message in InQ is NOT deleted.
  3. Proxy keeps trying to pick message from InQ and push it to OutQ
Observation: If QOS is BestEffort then multiple messages found in OutQ, because business service will get executed in its own transaction context. If QOS is Exactly once then message is not placed in OutQ. i.e transaction is rolled back.

TC3: Error Case – Raise an error in Response pipeline:

Required Configuration:
  1. 'Same Transaction For Response' – 'UnChecked'.
  2. Raise Error Action: Place it response pipeline after invoking business service to push message.
Result:
  1. Proxy picks up the message from InQ and pushes it to OutQ
  2. Message in InQ is deleted.
Observation: Transaction is committed. Because the error is raised in Response pipeline and the “Same transaction for Response” is unchecked, which means request and response are executed in different threads/transaction.

TC4: Error Case – Raise an error in request/response pipeline by Checking “Same Transaction For Response”

Required Configuration:
  1. 'Same Transaction For Response' – 'Checked'.
  2. Raise Error Action: Place it request/response pipeline (doesn't matter)
  3. Test this scenario with setting QOS to BestEffort and Exactly Once.
Result:
  1. Proxy picks up the message from InQ and pushes it to OutQ
  2. Message in InQ is NOT deleted.
  3. Proxy keeps trying to pick message from InQ and push it to OutQ
Observation: If QOS is BestEffort then multiple messages found in OutQ, because business service will get executed in its own transaction context. If QOS is Exactly once then message is not placed in OutQ. i.e Transaction is rolled back.


Since the message is in InQ, Proxy service indefinitely keeps trying to pick message from InQ and push it to OutQ.

To avoid trying indefinitely, you have two approaches

Approach 1:
Use “Reply with Failure” action in error handler which makes the transaction to be committed. In case of both BestEffort & Exactly Once you see one message in OutQ and message is deleted in InQ.

Approach 2:
Set the retry delivery limit parameters on InQ in WLS console. This includes the following parameters, After changing the settings though it says restart is not required, I advise to restart the servers for the settings to be effective.


In this case the transaction within proxy wont get committed. So proxy tries till the message is in InQ. After the redelivery limit is reached, JMS server moves the message from InQ to ErrorQ.

I hope this gives you an insight on how as a developer you can influence Transactions in OSB to commit/rollback within OSB.