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.

Oracle SOA - Mediator Error Handling highlights

Mediator Error Handling

Business fault:

Business faults are application-specific and are explicitly defined in the service WSDL file. You can handle business faults by defining the fault handlers in Oracle JDeveloper at design time.


<faultName xmlns:ns1="http://xmlns.oracle.com/Customer"
 name="ns1:InvalidCustomer"> <!-- Qname of Business/SOAP fault -->
       <condition>
         <test>
contains($fault.<PART_NAME>/custid, 1011)
 </test>
<!-- xpath condition based on fault payload -->
         <action ref="ora-retry"/>
       </condition>
   </faultName>
 
When a reference service returns a business fault, the fault can be handled in the Mediator service component. The returned fault can be forwarded to another component, redirected to an adapter service such as a file adapter, or an event can be raised. However, if both a fault policy and fault handler are defined for a business fault, then the fault policy takes precedence over the fault handler. In such a case, the fault handlers in the Mediator service component are ignored, if the fault policy is successfully executed.


 System Fault:

System faults occur because of some problem in the underlying system such as a network not being available. Mediator provides fault policy-based error handling for system faults.

Fault policies are not supported for the following:
  • Callback execution failures(Asynchronous and one-way Mediator components cannot handle system faults thrown from other SOA Suite components, such as a BPEL business process.)
  • Fault Handler action failures
  • Resequencer failures

The Mediator service engine throws only one fault, namely {http://schemas.oracle.com/mediator/faults}mediatorFault. Every Mediator fault is wrapped into this fault. The errors or faults generated by a Mediator can be captured by using the format shown in

<faultName xmlns:medns="http://schemas.oracle.com/mediator/faults" name="medns:mediatorFault">
<!-- mediatorFault is a bucket for all the mediator faults -->
     <condition>
       <test>
 contains($fault.mediatorErrorCode, "TYPE_FATAL_MESH")
 </test> 
<!-- Captures TYPE_FATAL_MESH errors -->
       <action ref="ora-retry"/>
     </condition>
   </faultName>

Fault policies for sequential routing rules are handled differently than for parallel routing rules

Sr No Sequencial Routing Rule Parallel Routing Rule
1. Transaction rolled back even if there is fault policy present Transaction does not rolled back if there is fault policy present
2. Fault return to the caller if there is no fault ploicy Human intervention action is deault action if there is no fault policy
3. Only Abort, Rethrow and Java actions are supported in fault policy and the specified actions are executed immediately in the caller's thread. Only Human Intervention, Retry, abort and Java action supported in fault policy
4. Mediator messages are not persisted in sequential routing Messages are persisted