Friday, 15 August 2008

Although there’s a bunch of stuff out there about transaction handling, bpel and esb, see copied links for a start, it still took me some time to figure out who to get it to work..

So, I’ll just add one to the number of blogs / discussions out there

The goal is to have a bpel process that calls two ESB services. If the second fails, the first should be rolled back.

I have two ESB services. These two ESB services both consist of a routing service in front of a Database adapter service. Both DB adapter services write a record to the database. The first write always is ok, the second should fail.

The BPEL process calls both ESB services as a partner link, within a scope S1.

Crucial in the bpel.xml are the transaction property and the preferredPort properties on both partnerlink definitions, and also the transaction property in the configurations section. This “configurations” section you need to add yourself in a text editor.

The preferredPort you can get from the ESB Routing service WSDL. Look for the esb binding port

<?xml version = '1.0' encoding = 'UTF-8'?>

<BPELSuitcase>

<BPELProcess id="testTransactionBPEL" src="testTransactionBPEL.bpel">

<partnerLinkBindings>

<partnerLinkBinding name="client">

<property name="wsdlLocation">testTransactionBPEL.wsdl</property>

</partnerLinkBinding>

<partnerLinkBinding name="PL1">

<property name="wsdlLocation">http://mysoa.com:7777/esb/wsil/DefaultSystem/Insert1?wsdl</property>

<property name="transaction">participate</property>

<property name="preferredPort">__esb_Insert1_execute_ppt</property>

</partnerLinkBinding>

<partnerLinkBinding name="PL2">

<property name="wsdlLocation">http://mysoa.com:7777/esb/wsil/DefaultSystem/Insert2?wsdl</property>

<property name="transaction">participate</property>

<property name="preferredPort">__esb_Insert2_execute_ppt</property>

</partnerLinkBinding>

<partnerLinkBinding name="HelloRandstad">

<property name="wsdlLocation">http://mysoa.com:7777/orabpel/default/HelloWorld/HelloWorld?wsdl</property>

</partnerLinkBinding>

</partnerLinkBindings>

<configurations>

<property name="transaction">participate</property>

</configurations>

</BPELProcess>

</BPELSuitcase>

The drawback of this is that you also lose your instance.

You can workaround this by adding an exception handling section to the bpel process on the scope S1. In the exception handling you call some bpel error handling / registration process. In my case I just called a version of the HelloWorld process. Then, after this call you throw a bpelx:rollback. The rollback section you just add in the text editor.

<faultHandlers>

<catchAll>

<sequence name="Sequence_1">

<invoke name="Invoke_3" partnerLink="HelloWorld"

portType="ns9:HelloWorld" operation="process"

inputVariable="Invoke_3_process_InputVariable"

outputVariable="Invoke_3_process_OutputVariable"/>

<throw name="Throw" faultName="bpelx:rollback"/>

</sequence>

</catchAll>

</faultHandlers>

The result, you have no inserts in the database, no instance of the actual bpel process, but a HelloWorld instance. This shows you something went wrong.