Sunday, June 12, 2011

Understanding Transaction in SOA Suite 11g with an example

I was working on a scenario to see how transaction works in soa suite 11g and i got to learn a lot of things.Well its not totally related to transaction but still i learned a lot from my exercise and in this post i will be sharing with you my experience and challenges that i have faced during this.

My composite looks flow is

There is an inbound adapter which is polling on a database.
The process starts with picking data from database and then it call another database adapter to insert data into a separate table,
After that i have a file adapter which is writing to a file.

My logic is that i will revoke the write privilege from the folder where i am suppose to write my file,This will cause an error.

so my process should roll back that both inbound and outbound database adapter should not be affected,it should not commit anything.


This will become more clear with the design and then checking the flow.So My bpel process looks something like this.Check out i have designed it initially as asynchronous process.



Now i am using following configuration for my inbound adapter that is polling the record from database and file adapter

<property name="jca.retry.count" type="xs:int" many="false" override="may">2</property>
<property name="jca.retry.interval" type="xs:int" many="false"
override="may">1</property>

Which means the inbound will retry for 2 times as well as the file adapter will try 2 times we will check it in our result to see what exactly happens.

In my case i have intentionally revoked the write privilege from the folder so that it throws a fault.

As you can see it creates one instances and within that instance there are three occurence for calling the file adapter.



This is because we have configured retry for 2 time so original + 2more retry makes it three.

However the inbound db adapter didn't retry as this is a asynchronous process.Had it been a synch process it would have retried even for inbound adapter.

Now what is our expectation in this process.We expect that since file is not written and we got error the other two adapter that is db outbound should not update the table and similarly the inbound db adapter should not remove the record from its table.But this doesn't happen.though it doesn's write record in outbound db adapter but it removes the record from the inbound db adapter.

Now how to achieve our required feature so that neither the record is updated in outbound db adapter nor the record in inbound db adapter is removed.this can be done by making this process a synchronous process.

So as you can see our process starts with the polling of database table which is by default a asynchronous process so just go to the wsdl of the inbound db adapter.

We know that in a synchronous process the request and response message lie in the same operation.So we will modify the process operation and will include an output message also.

so i just added the input message type and changed it to output as can be seen below.

<wsdl:portType name="poll_ptt">
<wsdl:operation name="receive">
<wsdl:input message="tns:SandyCollection_msg"/>
<wsdl:output message="tns:SandyCollection_msg"/>
</wsdl:operation>
</wsdl:portType>

Now just add a reply activity at the end of your process and connect it to the input polling adapter ,when asked for variable just mention the message type you have just created in the wsdl.




So now your process should look something like this after making this process a synchronous one.



Now try to redeploy this process and check the output how does it work.

Now here you will find an interesting scenarion.

Now you will find three instance is getting created this is because this is a synchronous process and we have defined a retry parameter of 2 in inbound db adapter so three instances are getting created for me.

And in each instance the file adapter has been retried twice (including original thrice) as can be seen by opening any errored instance.



Now i checked the inbound table and the record is deleted i checked the outbound table the record is not inserted so still i am not able to get the functionality which i was trying to attain.

But i noticed one thing during the time my process was retrying the record was there in inbound db adapter table as soon as the retry for inbound adapter ends the record gets deleted from the table so if we can somehow set the inbound adapter to retry for unlimited number of time we may be able to attain our functinality.

By default if you have not defined any retry parameter for inbound adapter it is set to infinite as it take the global value for inbound adapter which is set to infinity.this setting you can find in following location.


Go to your em console.

http://host:port/em

Right click on soa-infra

Administration and Systme Mbean Browser



Now here go to oracle.as.soainfra.config

your server then AdapterConfig and then adapter

Now on the right hand side you will find a property called as
GlobalInboundJcaRetryCount

This is by defaule set to unlimited "-1"

So by default if you have not specified any retry parameter in your composite the inbound adapter you keep on trying and you will get instances generated on regular interval of polling interval.But the retry parameter set in composite takes a precedence ove the GlobalInboundJcaRetryCount parameter.So if we will remove the retry parameter from our composite from our inbound adapter then this will poll for indefinite period of time and your data from inbound database table will not be picked.



I removed the retry parameter and then tested this issue and i achieved the functionality that neither the record was deleted from the inbound table nor it was written to the outbound db table.

This infact is not a best approach to design rather we should define fault policies to catch this fault and take appropriate action or we should define compensation handler to take care of such situation.But again if you consider it in real life scenarion once the instance is completed if it is failed then ideally everything should roll back but in our case if we will rollback the record will be polled continously so we should take care of these situation by defining fault handling mechanism to store the faulted record.

1 comment:

Anonymous said...

U r blog is really helpful.
Gr8 going......