This is basically a continuation of my previous post
http://soa-bpel-esb.blogspot.com/2011/06/understanding-transaction-in-soa-suite.html
where in i have tried to explain transaction in soa suite 11g.
there was a single composite instance and we had seen how it was working.
In this exercise we will see how transaction semantics work in soa suite 11g when we have different composites.
I will use the same process which i have used in my previous post.
http://soa-bpel-esb.blogspot.com/2011/06/understanding-transaction-in-soa-suite.html
I will only make a small change in the process.
Instead of calling a db adapter directly i will call another bpel process which is doing the same operation of inserting data in to the same table.
So my functionality remains the same,the only changes is that i am calling a new process to update the database that too i am doing intentionally to show how a separate process starts a new transaction.
this will be very much clear with the example.
I have two process at my end.The first process is just taking an input and calling database adapter to update the record.It looks like this.
Lets Call this process subprocess for understaning purpose.
Now i have a main process where in the flow is like this.
there is an inbound database adapter listening on a table for records.
It is then calling this subprocess to update the record and then it is calling a file adapter to write files in to some folder location.Here also i will revoke the write privilege from this folder to force cause an exception.
So my Main process looks something like this.
Now in my subprocess which is basically a db adapter outbound operation i have following settings for outbound retry
<property name="jca.retry.count" type="xs:int" many="false" override="may">4</property>
<property name="jca.retry.interval" type="xs:int" many="false"
override="may">1</property>
<property name="jca.retry.backoff" type="xs:int" many="false"
override="may">2</property>
<property name="jca.retry.maxInterval" type="xs:string" many="false"
override="may">120</property>
Again in my Main process i have following retry parameter for inbound db adapter
<property name="jca.retry.count" type="xs:int" many="false" override="may">10</property>
<property name="jca.retry.interval" type="xs:int" many="false"
override="may">1</property>
And following retry parameters for my outbound 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>
Now with this configuration i will try to test my process and see what is the result.
Now you can see that i have specified an inbound db adapter retry value of 10 so we have 11 instance created ,
Again for file adapter i have specified a retry factor of 2 so we have three instance of file adapter created.
Now i will check my sub process ,i can also see 11 instances have created for my sub process also that is my outbound db adapter has update the table 11 times,this is not what i need,ideally since my file adapter was not able to write file it should not have written any records to outbound db table.
This happens because by deafult a new process when linked to an existing process starts its own transaction so the sub process is starting a new transaction and hence there are 11 different instance for the sub process.
Now we want to achieve that when file adapter is not able to write the file into the specified folder no record should be written in to the outbound db adapter and the record from inbound database table should also not be deleted.
To achieve this target
We need to make the Sub process in a single transaction with the Main Bpel process.
To make the sub process to work in a same transaction as that of main process we need to add the following property in our composite.xml of sub process.
<property name="bpel.config.transaction" many="false" type="xs:string">required</property>
Please have a look in the following document to get idea on this property as to where exactly we should use this property
http://download.oracle.com/docs/cd/E17904_01/integration.1111/e10224/soa_transactions.htm#SOASE85811
So now as you can see here i have specified this property in my Sub Process.
Now we need one more configuration,that is by default the inbound db adapter has an infinite number of retry as stated in following document
By default, there is unlimited retry for inbound errors
http://download.oracle.com/docs/cd/E17904_01/integration.1111/e10231/life_cycle.htm#TKADP1892
it also says
In this case, where you set the default value of jca.retry.count to a finite number, even if you do not explicitly configure a value for the jca.retry.count property for a particular inbound adapter endpoint, the global default takes effect.
so we will remove the retry parameters from our inbound adapter and see so that it can take value from GlobalInboundJcaRetryCount which is set to infinite by default.In my previous post i have mentioned how to check this value.
http://soa-bpel-esb.blogspot.com/2011/06/understanding-transaction-in-soa-suite.html
Now we will redploy our whole process and see what is the result ,if we are able to acheive the required functionality.
I redeployed and tested my process.
Now here is my result.
The inbound adapter is polling indefinitely on the input db adpater and it is callin the Sub process but this time the data in the outbound table is not getting updated.so we have acheieved the fucntionality that we wanted to have in two different process by making them participate in a single transaction.
Now just to check my process if it works fine in case when i allow the write permission.
I gave the write permission in my folder location and i saw following results.
The record is deleted from inbound db table
A record is updated in the outbound db table and
a file is written into the folder location.
so this is the perfect scenario i was looking for.
As you can see i have my Sub Process as a syncrhonous process.
If i will make my subprocess as a asynchronous process then i need not do any configuration that is by default the sub process will participate in the same transaction as the main process.This is as per document
http://download.oracle.com/docs/cd/E17904_01/integration.1111/e10224/soa_transactions.htm#SOASE85811
12.1.1 Oracle BPEL Process Manager Transaction Semantics
As with previous releases, Oracle BPEL Process Manager by default creates a new transaction on a request basis. That is, if a transaction exists, it is suspended, and a new transaction is created. Upon completion of the child (new) transaction, the master (suspended) transaction resumes.
However, if the request is asynchronous (that is, one-way), the transaction is either:
Inherited for insertion into the dehydration store (table dlv_message).
Enlisted transparently into the transaction (if one exists).
So As per my understanding asynchronous process should participate in the same transaction as the main process as i can see i am getting the same fucntionality as i have achieved with synchronous process and following settings in the composite.
<property name="bpel.config.transaction"
many="false" type="xs:string">required</property>
I might be wrong but that is what i have understood,so if my understanding is correct we need not create a synchronous bpel process to update the record in our sub process.May be i am missing something and reviewer can correct me on the same.
6 comments:
Nice article,Can you please post a similar article for fault handling mechanism in multiple composites and how the fault is propagated.
I wanted to have a one way bpel process in BpelCallee let me know the configuration required for a one way process.
Great job,Keep doing good work.
Thanks
Good one........clarifies a lot.
Very Well Explained
Very Well Explained
Post a Comment