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. |
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
In my next post i will cover bpel.config.transaction=required scenario.
quite clear explanation , thanks for sharing it with example
ReplyDeleteVery nice!!
ReplyDeleteDipankar
https://dipankarhazrabanerjee.wordpress.com/
Awesome
ReplyDelete