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.
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..