13 Transaction and Fault Propagation Semantics in BPEL Processes

This chapter describes transaction and fault propagation semantics in Oracle BPEL Process Manager. It describes how to configure the transaction behavior for BPEL instances with initiating calls and the execution of one-way invocations.

This chapter includes the following sections:

13.1 Introduction to Transaction Semantics

Transaction semantics in release 11g enable you to use the underlying Java Transaction API (JTA) infrastructure used in the execution of components. This section describes transaction semantics for Oracle BPEL Process Manager

13.1.1 Oracle BPEL Process Manager Transaction Semantics

As with previous releases, Oracle BPEL Process Manager by default creates a new transaction on a request basis. That is, if a transaction exists, it is suspended, and a new transaction is created. Upon completion of the child (new) transaction, the master (suspended) transaction resumes.

However, if the request is asynchronous (that is, one-way), the transaction is either:

  • Inherited for insertion into the dehydration store (table dlv_message).

  • Enlisted transparently into the transaction (if one exists).

There is no message loss. Either the invocation message is inserted into the dehydration store for processing or the consumer is notified through a fault.

In release 10.1.3.x, there were several properties to set on the consuming process (that is, on the partner link) and the providing process. This enabled you to chain an execution into a single global transaction. On the consuming side, you set transaction=participate on the partner link binding in the bpel.xml file. On the providing side, you set transaction=participate in the <configurations> section of bpel.xml.

In release 11g, you only must set a new transaction property on the BPEL component being called (known as the callee process). You add bpel.config.transaction as follows:

  • In the Create BPEL Process dialog for a new BPEL process.

  • In the BPEL process service component section in the composite.xml file of an existing BPEL process (note the required prefix of bpel.config.).

This property configures the transaction behavior for BPEL instances with initiating calls.

Example 13-1 provides details.

Example 13-1 Setting a New Transaction

<component name="InternalWarehouseService">
    <implementation.bpel src="InternalWarehouseService.bpel"/>
    <property name="bpel.config.transaction" 
         many="false" type="xs:string">required | requiresNew</property>
  </component>

There are two possible values: required (the default value) and requiresNew. Table 13-1 describes these values and summarizes the behavior of the BPEL instance based on the settings.

Table 13-1 bpel.config.transaction Property Behavior

For... With bpel.config.transaction Set to required... With bpel.config.transaction Set to 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.


Note:

The bpel.config.transaction property does not apply for midprocess receive activities. In those cases, another thread in another transaction is used to process the message. This is because correlation is needed and it is always done asynchronously.

For additional information about setting the bpel.config.transaction property, see Section 4.1.1, "How to Add a BPEL Process Service Component" and Section C.1.1, "How to Define Deployment Descriptor Properties in the Property Inspector."

The following sections describe the transaction and fault behavior of setting bpel.config.transaction to either required or requiresNew.

13.1.1.1 BPELCaller Process Calls a BPELCallee Process That Has bpel.config.transaction Set to requiresNew

In Table 13-2, the BPELCaller process calls the BPELCallee process. The BPELCallee process has the property bpel.config.transaction set to requiresNew. Table 13-2 describes fault propagation and transaction behavior when bpel.config.transaction is set to this value.

Table 13-2 BPELCaller Calls BPELCallee That Has bpel.config.transaction Set to requiresNew

If The BPELCallee... Then The BPELCallee Transaction... And The BPELCaller...

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.

Replies back with a fault (FaultOne), and then throws a fault (FaultTwo).

Is rolled back.

Gets FaultTwo.

Throws a bpelx:rollback fault (that is, it uses <throw>).

Is rolled back.

Gets a remote fault.


For information about specifying the bpelx:rollback extension with a throw activity, see Section 12.7.3, "How to Roll Back Activities with a bpelx:rollback Extension in a Throw Activity."

13.1.1.2 BPELCaller Process Calls a BPELCallee Process That Has bpel.config.transaction Set to required

In Table 13-3, the BPELCaller process calls the BPELCallee process. The BPELCallee process has the property bpel.config.transaction set to required. Table 13-3 describes fault propagation and transaction behavior when bpel.config.transaction is set to this value.

Table 13-3 BPELCaller Calls BPELCallee That Has bpel.config.transaction Set to required

If The BPELCallee... Then The BPELCaller...

Replies with a fault (that is, it uses <reply>).

Gets the fault and can catch it. The BPELCaller owns the transaction. Therefore, if it catches it, the transaction is committed. If the BPELCaller does not handle it, a global rollback occurs.

Throws a fault (that is, it uses <throw>).

Gets the fault and can catch it.

Replies back with a fault (FaultOne), and then throws a fault (FaultTwo).

Gets FaultTwo.

Throws (that is, it uses <throw>) a bpelx:rollback fault.

Gets its transaction rolled back; there is no way to catch it. This fault cannot be handled.


As an example, assume you create two synchronous processes (BPELMaster and BPELChild) that each use the same database adapter reference to insert the same record (and therefore, causes a permission key (PK) violation). The xADatasourceName is set for both.

Without bpel.config.transaction set, after the fault occurs, and it is not handled, BPELChild is rolled back. If BPELMaster has a catch block, its transaction is committed. Therefore, you end up with the record from BPELMaster in the database.

If you do not catch the fault in BPELMaster as well, you get a second rollback (however, in two different transactions).

If bpel.config.transaction is set to required for the same test case and no fault handlers are in place, the entire transaction is rolled back based on BPELMaster's unhandled fault.

If you add a fault handler in BPELMaster to catch the fault from BPELChild and throw a rollback fault, the transaction is globally rolled back.

This feature enables you to control transaction boundaries and model end-to-end transactional flows (if your sources and targets are also transactional).

For information about specifying the bpelx:rollback extension with a throw activity, see Section 12.7.3, "How to Roll Back Activities with a bpelx:rollback Extension in a Throw Activity."

13.2 Introduction to Execution of One-way Invocations

A one-way invocation (with a possible callback) is typically exposed in a WSDL file as shown in Example 13-2.

Example 13-2 WSDL File Exposure

<wsdl:operation name="process">
        <wsdl:input message="client:OrderProcessorRequestMessage"/>
    </wsdl:operation>

This causes the BPEL process service engine to split the execution into two parts:

  • For the first part, and always inside the caller transaction, the insertion into the dlv_message table of the dehydration store occurs (in release 10.1.3.x, it was inserted into the inv_message table).

  • For the second part, the transaction and the new thread execute the work items, and a new instance is created.

This has several advantages in terms of scalability, because the service engine's thread pool (invoker threads) executes when a thread is available. However, the disadvantage is that there is no guarantee that it executes immediately.

If you require a synchronous-type call based on a one-way operation, then you can use the onewayDeliveryPolicy property, which is similar to the deliveryPersistPolicy property of release 10.1.3.x.

Specify bpel.config.oneWayDeliveryPolicy as follows:

  • In the Create BPEL Process dialog for a new BPEL process.

  • In the BPEL process service component section of the composite.xml file for an existing BPEL process.

If this value is not set in composite.xml, the value for oneWayDeliveryPolicy in the System MBean Browser in Oracle Enterprise Manager Fusion Middleware Control is used. The following values are possible.

  • async.persist: Messages are persisted in the database. With this setting, reliability is obtained with some performance impact on the database. In some cases, overall system performance can be impacted. This is the default value.

  • async.cache: Incoming delivery messages are kept only in the in-memory cache. If performance is preferred over reliability, consider this setting. When set to async.cache, if the rate at which one-way messages arrive is much higher than the rate at which they are delivered, or if the server fails, messages can be lost. In addition, the system can become overloaded (messages become backlogged in the scheduled queue) and you can receive out-of-memory errors. Consult your own use case scenarios to determine if this setting is appropriate.

    When you set oneWayDeliveryPolicy to async.cache in high availability environments, invoke and callback messages in the middle of execution at the time of a server crash may be lost or duplicated. Server failover is not supported for async.cache. For more information, see Oracle Fusion Middleware High Availability Guide.

  • sync: Direct invocation occurs on the same thread. The scheduling of messages in the invoke queue is bypassed, and the BPEL instance is invoked synchronously. In some cases this setting can improve database performance.

For more information about setting the bpel.config.oneWayDeliveryPolicy property, see Section 4.1.1, "How to Add a BPEL Process Service Component" and Section C.1.1, "How to Define Deployment Descriptor Properties in the Property Inspector."

Table 13-4 describes the behavior when the main process calls the subprocess asynchronously. Table 13-4 is based on the use cases described in Section 13.1.1.1, "BPELCaller Process Calls a BPELCallee Process That Has bpel.config.transaction Set to requiresNew" and Section 13.1.1.2, "BPELCaller Process Calls a BPELCallee Process That Has bpel.config.transaction Set to required."

Table 13-4 Main Process Calls the Subprocess Asynchronously

If... If The Subprocess Throws Any Fault... If The Subprocess Throws a bpelx:rollback...

onewayDeliveryPolicy=async.persist

(The BPELCallee process runs in a separate thread/transaction.)

The BPELCaller does not get a response because the message is saved in the delivery service. The BPELCallee transaction is rolled back if the fault is not handled.

The BPELCaller does not get a response because the message is saved in the delivery service. The BPELCallee instance is rolled back on the unhandled fault.

onewayDeliveryPolicy=sync

and

transaction=requiresNew

(The BPELCallee runs in the same thread, but a different transaction.)

The BPELCaller receives a FabricInvocationException. The BPELCallee transaction rolls back if the fault is not handled.

The BPELCaller receives a FabricInvocationException. The BPELCallee transaction is rolled back.

onewayDeliveryPolicy=sync

and

transaction=required

(The BPELCallee runs in the same thread and the same transaction.)

The BPELCallee faulted. The BPELCaller receives a FabricInvocationException. The BPELCaller has a chance to handle the fault.

The whole transaction is rolled back.

onewayDeliveryPolicy=async.cache

and

transaction=requiresNew

or

transaction=required

The BPELCaller does not get a response because the caller thread returns before the request is handled. The BPELCallee transaction is rolled back if the fault is not handled. The message is lost because it is not saved in the database.

The BPELCaller does not get a response because the caller thread returns before the request is handled. The BPELCallee transaction is rolled back if the fault is not handled. The message is lost because it is not saved in the database.


For information about specifying the bpelx:rollback extension with a throw activity, see Section 12.7.3, "How to Roll Back Activities with a bpelx:rollback Extension in a Throw Activity."