A long-running BPEL process spans multiple transactions.
Each transaction is triggered either by a Java™ Messaging
Service (JMS) message or by a work-manager-based implementation.
The following aspects of transactional behavior are described here:
Overview
The following diagram
shows how each navigation step in a long-running process is performed
in its own transaction. A navigation step can span multiple activities
as shown by the invoke activity that calls a service. Also, multiple
activities can be run in one transaction as long as a transaction
failure does not occur. For more information about transaction failures,
see Recovery from transaction failures.
To allow
navigation across transaction boundaries, the states of the process
instance and its activity instances are persisted in the database.
You can influence transaction boundaries by using the transactional
behavior attribute. However, Business Process Choreographer can add
or remove transaction boundaries at any time.
In general, a
transaction boundary is needed in the following situations:
- When waiting for an external request, that is, upon reaching a
receive activity or pick activity (also known as a receive choice
activity) in the process navigation for which a corresponding request
has not been received yet
- When scheduling a timer for a wait activity
- When invoking a service asynchronously using an invoke activity
- When invoking a human task activity
In addition, Business Process Choreographer introduces
transaction boundaries in the following situations. However, your
process design must not rely on these boundaries because they can
be overridden during process navigation, or they might change in the
future.
- When a fault is raised during process navigation
- Before and after an invoke activity is started that invokes a
service synchronously, and this service does not participate in the
transaction of the process
- When propagating lifecycle operations to child processes, for
example, when a parent process is suspended, its child processes are
suspended in subsequent transactions
- When the process instance is to be deleted automatically upon
completion of the process
- When trying to recover from a failure that causes the rollback
of a transaction spanning a series of activities
- Where specified using the transactional behavior attribute
Influencing transaction boundaries
When
you model a business process, you can suggest transaction boundaries
for certain types of activities, such as, invoke, snippet, and human
task activities by changing the transactional behavior attribute of
the activity. The transactional behavior attribute is ignored if an
invoke activity calls a synchronous service that does not participate
in the current transaction. In this case, there is always a transaction
boundary before the invoke activity is started, and after the invoke
activity completes.
The attribute can take one of the following
values:
- Commit before
- The current transaction is committed, and a new transaction is
started. The activity with this attribute value becomes the first
activity of the new transaction.
- Commit after
- The activity participates in the current transaction. After the
activity completes successfully, the transaction is committed, and
a new one is started. A new transaction is started for each immediately
following activity, and each subsequent activity becomes the first
activity of one of these new transactions.
- Participates
- The activity participates in the current transaction. Additional
transaction boundaries are not set, neither before nor after the activity.
In
the following situations, this setting allows the transaction to continue
with the navigation of the following activities depending on the values
of their settings of the transactional behavior attributes.
- If the invoke activity invokes the service asynchronously, the
arrival of the response message triggers a new transaction. The transaction
is short because it commits immediately after the status of the invoke
activity is updated.
- In a sequence of human task activities, two transactions are needed
for each human task activity, one to activate the human task activity
and another to complete the human task activity. If you change the
setting to Participates, you can reduce the number
of transactions to one for each human task activity. This is because
the completion of the previous human task activity, and the activation
of the following activity are performed in the same transaction.
- To enable server-controlled page flows that use the completeAndClaimSuccessor API.
- Requires own
- The activity runs in its own transaction. This means that the
current transaction is committed before the activity starts, and a
new transaction starts after this activity completes.
You can also determine whether the transaction
that initiates the process is committed after the receive activity,
or the receive action of the receive-choice (pick) activity completes
by changing the transactional behavior attribute of the corresponding
activity. For initiating receive and receive-choice activities, the
attribute can take one of the following values:
- Commit after
- After the activity completes successfully, the transaction that
initiates the process is committed, and a new one is started. This
setting is useful if you invoke the process instance using a synchronous
API call.
- Participates
- The transaction that initiates the process continues after the
activity completes. This setting is required if you want to invoke
the process instance using the initiateAndClaimFirst API.
With this API, you can create a process instance and immediately claim
the first human task.
If your process invokes another BPEL process,
ensure that the corresponding invoke activity is not part of the transaction
that initiates the process. You can achieve by setting the transaction
behavior attribute in one of the following ways:
- Set the attribute of the initiating receive or receive choice
activity to Commit after
- Set the attribute of the invoke activity to Commit before or Requires
own
Concurrent navigation of parallel
branches in flow activities
To achieve concurrency in the
navigation of parallel branches in a flow activity, a new transaction
boundary is needed at the beginning of each branch so that each parallel
activity is processed in a separate transaction. This means that the
transactional behavior attribute of the first activity of each parallel
branch must be set to Commit before or Requires
own to achieve parallelism from the beginning of the flow.
Note: For an Oracle database, navigation transactions
for parallel branches in a process instance are serialized, that is
they cannot be run in parallel. This is because the locks on database
entities are not as granular as, for example, those for DB2® databases.
However, services triggered asynchronously by such parallel branches
still run in parallel; it is only the process navigation that is serialized
for these database systems.
Concurrent navigation of branches
of a parallel forEach activity
The processing of each branch
of a parallel forEach activity is started in its own, separate transaction.
Thus parallel execution of these branches is enabled.
Note: For an Oracle database, navigation transactions for
parallel branches in a process instance are serialized, that is they
cannot be run in parallel. This is because the locks on database entities
are not as granular as, for example, those for DB2 databases.
However, asynchronous services on the branches of a parallel forEach
activity are executed concurrently, thus parallelism forEach activities
can be achieved.
Invoked services and transactions
in long-running processes
A service that is called within
a long-running process using an invoke activity can either participate
in the current transaction of the long-running process, or it can
run in its own transaction.
The following settings determine
whether the service participates in the transaction of the long-running
process or runs in its own transaction.
- The interaction style that is used to call the service.
The
interaction style can be synchronous or asynchronous. The style is
determined by the preferred interaction style of the target SCA component
or SCA import, as shown in the following table:
Table 1. | Preferred interaction style of target component
or import |
One-way operation |
Request-response operation |
| Any |
Asynchronous invocation |
Asynchronous invocation |
| Synchronous |
Synchronous invocation |
Synchronous invocation |
| Asynchronous |
Asynchronous invocation |
Asynchronous invocation |
- The Service Component Architecture (SCA) transaction qualifiers
that are specified for the process and the service that is called:
Recovery from transaction failures
A
transaction in a long-running process can roll back for various reasons,
such as:
Recovery of a successful service invocation
when a transaction rolls back
The recovery behavior depends
on whether the called service participates in the current transaction.
An
invoke activity calls a service that participates in the current transaction.
The execution of the service is complete. If an error occurs after
completion of the service and the transaction is rolled back to the
state that the process was in before the transaction started, the
effect of the called service is also rolled back. When the transaction
is retried, the service is called again.
In contrast, if the
called service does not participate in the current transaction and
the called service returns a response, the response is stored in a
separate transaction. If an error occurs after the response is stored,
the current transaction is rolled back and the transaction is retried.
During the retry the service is not called again, however, the stored
response is restored and the navigation continues.
Recovery of a service invocation
that results in a runtime exception
If a transaction fails
because the service invocation throws a runtime exception and enforces
a rollback, the message that triggered the transaction stays on the
Business Process Choreographer internal queue for JMS navigation or
in the work manager, and the message retry count is increased by one.
The retry behavior depends on whether the transaction contains a single
activity or spans multiple activities.
- Transactions with a single activity
- The activity is retried in a new transaction.
- Transactions spanning multiple activities
- When the transaction is retried, the transaction boundaries are
scaled down so that the transaction is committed after each of the
activities completes. In this way, the failure can be narrowed down
to the activity that is causing the exception.
- Example of scaling down transaction boundaries
- A transaction step spans multiple activities {A1 through An}.
If a runtime exception is returned by the activity An, and
the transaction is marked for rollback, the transaction boundaries
are scaled down to {A1} and {A2 through An}. If the activity
An returns the runtime exception again, the transaction boundaries
are now scaled down to {A2} and {A3 through An}. This adjustment
of the transaction boundaries is repeated until the activity An runs
in its own transaction {An}. If the activity An still
returns the runtime exception, and the transaction is marked for rollback,
the exception is then stored in a local transaction. When the {An}
transaction in retried, the exception information is available without
invoking the implementation of activity An again.
The subsequent
processing of the activity An depends on the value of the Continue
processing upon unhandled faults setting for the activity.
Tip: If you want a set of activities in a long-running process
to always be invoked in a single transaction, factor out the business
logic for these activities into a microflow, and invoke it as a subprocess.
The logic of a microflow is always run in a single transaction.