Tuesday 20 September 2011

Transaction Processing in BPEL Processes

Closing the Transaction

Just been working with a couple of colleagues on documenting how to migrate transactional processes from WebLogic Integration (WLI) to BPEL and thought I would blog about transaction support in BPEL.  First off there are a couple of contradictory statements that need to be made.
  • BPEL does not have transaction delineation
  • Oracle BPEL Process Manager supports transactions
The first statement relates to the BPEL language which has no way of marking the start or end of XA style transactions, instead it provides semi-automated recovery through the concept of compensation, but more on this in another entry.
The second statement relates to the Oracle implementation of BPEL.  BPEL is inherently a stateful language and the BPEL Process Manager uses XA transactions to manage that state.  It also allows XA transactions to extend beyond the boundaries of the active BPEL process.  In this post I will try to explain a little about how this works.

Transactions Everywhere

Every BPEL process executes in the context of one or more transactions.  When a process starts to execute the process manager does one of two things with transactions;
  1. It starts a new transaction for the process.
  2. It enlists the process in an already open transaction.
BPEL uses this transaction to update process state in the database and also log audit events in the database.  Even if all this is turned off the process manager will still have processes execute in a transaction context.  When invoked through a web service interface BPEL will use the first option as there will not be a transaction context available.  When invoked through the Java API in a transactional environment then the process manager may use either option depending on the parameters used in the call.

Lazy Boy

BPEL will try to squeeze as many activities into a single transaction as it possibly can.  Only a few activities actually cause the process manager to update the process state in the database and commit the transaction.  A given activity does not always cause a transaction to be committed, sometimes the process may keep the same transaction context because of the properties associated with the activity.

Enlisting Support with a Little Participation

When BPEL calls an adapter, the ESB or another process in the same BPEL domain then it has the option to either include the target in the same transaction, or to start a separate transaction.  This behavior is controlled by the “transaction” property in the partner link.  If the “transaction” property value is set to “participate” then the callee is enlisted into the current transaction, if it is unset or set to any other value then the callee executes in a seperate transaction.  This is great for ensuring that several database updates are all included as part of the same transaction, but it does have a downside.  If any of the callees rolls back the exception then the the current BPEL process state is also rolled back to the last commit.  If there has been no commit and this process was invoked through a synchronous interaction then the process will seem to disappear from the face of the earth.  Something to be aware of.  To minimise the impact of this the database adapter will throw an error rather than rollback the transaction if by so doing it would not affect transactional integrity (basically you can do one DB update without rolling back but if you do two then an error will cause a rollback).

Parallel Execution

You might think that a BPEL flow activity would cause a new transaction to be started as this allows several activities to be executed in parallel. However this is not the case as the BPEL Process Manager will try to execute the flows sequentially for efficiency purposes.  Only if some action in the flow would cause a new transaction to be started will the activities execute in parallel.  A common use case for this is when a flow is used to make several synchronous calls.  Normally they would all execute in the same transaction context, however this means that the services are called sequentially, which can add latency to the application.  To avoid this there is another partner link property, “nonBlockingInvoke”, which when set to “true” causes a new thread to be spawned to execute the invoke.  The upshot of this is that a new transaction is started and this allows for true parallelism in the flow.

Lets Talk About Commitment

The general rules about what causes a commit are pretty straightforward, the BPEL process will commit the transaction and start a new one after the following activites
  • receive – unless it is the first receive in the process and the process was called with a “transaction=participate” property (possibly by marking it as such in the partner link) in which case the process participates in the already existing transaction.
  • onMessage
  • wait – for very short waits (up to a couple of seconds) the process manager will not commit the transaction.
  • onAlarm
  • invoke – only if the partner link is non-idempotent (can be marked with the “idempotent” partner link property).
  • End of process flow – only if the process is not participating in the callers transaction (the corollary of the receive).
The table below summarises the transaction status when performing different activities.

Activity

Transaction Status in BPEL Process

Transaction Status in Target Process or Adapter

Receive New Transaction N/A
Receive with Property “transaction=participate” Use Existing Transaction from Caller N/A
Invoke Synchronous Process Use Existing Transaction New Transaction
Invoke Synchronous Process with Partner Link Property “transaction=participate” Use Existing Transaction Use Existing BPEL Transaction
Invoke Synchronous Process with Partner Link Property “idempotent=false” New Transaction New Transaction
Invoke Synchronous Process with Partner Link Property “nonBlockingInvoke=true” New Transaction New Transaction
Invoke Asynchronous Process Use Existing Transaction New Transaction
Invoke Asynchronous Process with Partner Link Property “transaction=participate” Use Existing Transaction New Transaction
Invoke Synchronous Process with Partner Link Property “idempotent=false” New Transaction New Transaction
Wait < a couple of seconds Use Existing Transaction N/A
Wait > a couple of seconds New Transaction N/A
Flow Use Existing Transaction  

Flow

You may be surprised to see flow on the list, and then even more surprised to see that it uses the existing BPEL transaction context.  The reason for this is that the BPEL process manager will try to execute all the flow legs sequentially and so the behavior of the flow will be determined by the activities in the flow rather than the actual flow itself.

References

You can read more about transactional semantics (complete with pretty pictures that I think do a good job of explaining what is happening) in the Oracle SOA Suite Best Practices Guide chapter 1.
Clemens also blogged about this a while back here and here.

No comments:

Post a Comment

xslt padding with characters call template for left pad and right pad

  Could a call-template be written that took two parameters ?   a string, and a   number) return the string with empty spaces appended t...