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 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;- It starts a new transaction for the process.
- It enlists the process in an already open transaction.
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).
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 |
No comments:
Post a Comment