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.
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.
- Transaction will be commited if proxy service executes successfully without any errors.
- 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.
- 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:
- 'Same Transaction For Response' – 'Checked/Unchecked'(doesn't matter).
- Raise Error Action: Not Used in the flow.
Result:
- Proxy picks up the message from InQ and places it in OutQ
- Message in InQ is deleted.
Observation: As expected transaction
is committed
TC2: Error Case – Raise an error in
request pipeline
Required Configuration:
- 'Same Transaction For Response' – 'Checked/Unchecked'.
- Raise Error Action: Place it request pipeline after invoking business service to push message.
- Test this scenario with setting QOS to BestEffort and Exactly Once.
Result:
- Proxy picks up the message from InQ and pushes it to OutQ
- Message in InQ is NOT deleted.
- 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:
- 'Same Transaction For Response' – 'UnChecked'.
- Raise Error Action: Place it response pipeline after invoking business service to push message.
Result:
- Proxy picks up the message from InQ and pushes it to OutQ
- 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:
- 'Same Transaction For Response' – 'Checked'.
- Raise Error Action: Place it request/response pipeline (doesn't matter)
- Test this scenario with setting QOS to BestEffort and Exactly Once.
Result:
- Proxy picks up the message from InQ and pushes it to OutQ
- Message in InQ is NOT deleted.
- 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.