Friday, January 2, 2015

Oracle SOA 11g/12C - BPEL Transaction Handling Part 1


Sometime it's quite confusing to deal with BPEL trasactions when mutiple BPEL process involved in a SOA application. To make it simple to understand , i am going to create some sample scenario for  Synchronous and Asynchronous processes.

In BPEL process,  transaction behaviour depends upon the value of  bpel.config.transaction property.

bpel.config.transaction Property Behavior

Process Type bpel.config.transaction=required bpel.config.transaction=requiresNew
Request/response (initiating) invocations The caller's transaction is joined (if there is one) or a new transaction is created (if there is not one) A new transaction is always created and an existing transaction (if there is one) is suspended.
One-way initiating invocations in which bpel.config.oneWayDeliveryPolicy is set to sync Invoked messages are processed using the same thread in the same transaction A new transaction is always created and an existing transaction (if there is one) is suspended


To replicate above behaviour, i am going to create two BPEL process  MasterBPEL and ChildBPEL processes in sample composite application.Each use the same database adapter reference to insert the same record (and therefore, causes a permission key (PK) violation). We will find out how MasterBPEL process bahaves when we change the value of  bpel.config.transaction property in ChildBPEL process. I also cover different error handling scenario in this sample.


I have created a database table Employee with following property


 

ID field is a primary key.


XML Schema for the project .

<?xml version="1.0" encoding="windows-1252" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ex="http://www.example.org"
            targetNamespace="http://www.example.org" elementFormDefault="qualified">
  <xsd:element name="employees">
    <xsd:complexType>
    <xsd:sequence>
       <xsd:element name="employee" type="ex:employeeType"/>
       
    </xsd:sequence>
   
    </xsd:complexType>
    </xsd:element>
   
     <xsd:complexType name="employeeType">
    <xsd:sequence>
       <xsd:element name="id" type="xsd:int"/>
        <xsd:element name="name" type="xsd:string"/>
         <xsd:element name="age" type="xsd:string"/>
          <xsd:element name="adress" type="xsd:string"/>
    </xsd:sequence>
   
    </xsd:complexType>
   
    <xsd:element name="Response">
    <xsd:complexType>
    <xsd:sequence>
     <xsd:element name="result" type="xsd:string"/>
   </xsd:sequence>
   </xsd:complexType>
   </xsd:element>
   
</xsd:schema>


 Same schema will be used in both the BPEL process beacuse both processes going to insert same record in database.

MasterBPEL process will insert database record then invoke ChildBPEL processs. ChildBPEL process will try to insert same record into database and return the response/fault back  to MasterBPEL Process.


Composite application looks like this



MasterBPEL Process


bpel.config.transaction property



ChildBPEL process


bpel.config.transaction property



Different Scenarios


1. bpel.config.transaction=requiresNew   for  both  the BPELprocesses and error is  not handled in any  process.

If The ChildBPEL Process Then The ChildBPEL Process Transaction... MasterBPEL Process
Replies with a fault (that is, it uses <reply>). Is saved. Gets the fault and can catch it.
Throws a fault that is not handled (that is, it uses <throw>). Is rolled back. Gets the fault and can catch it.
Throws a bpelx:rollback fault (that is, it uses <throw>). Is rolled back. Gets a remote fault.


In this scenario transaction will be rolled back in  both the processes and no record will saved in the database.


Employee table before process execution








Execute MasterBPEl process from EM console .








 Following error will thrown by the master processs because when MasterBPEL process insert record in database it hold the lock, so ChilDBPEL proces not able to insert the record  and throw execption back to MasterBPEL process. As  MasterBPEL process is not handling this exception,  transaction will be rolled back. No record will be inserted in the employee table.



 There will not be any record in inserted in the employee table.




Add CatchAll block in MasterBPEL process , redeploy and  rerun the process.



  

ChildBPEL proces will throw following erro back to MasterBPEL Process





Process Audit Trail.




BPELMaster has a catch block, its transaction is committed. Therefore, you end up with the record from BPELMaster in the database.



 In this scenario even if ChildBPEL process throws rollback exception and  if  MasterBPEL process has catch block then transaction in MasterBPEL will be commited because ChildBPEL process does not particiapte in MasterBPEL process's transaction due to .bpel.config.transaction=requiresNew. ChildBPEL process returns remote fault.

Add catch block in ChildBPEL process and throw rollback exception



 

 Redeploy and rerun the process








Error




New Record inserted in the table by MasterBPEL process.







 In my next  post i will cover bpel.config.transaction=required scenario.

3 comments: