Details
-
New Feature
-
Status: Resolved
-
Major
-
Resolution: Fixed
-
1.2
-
None
-
platform-independent
Description
In general, WS-BPEL processes are susceptible to transient errors that stem from faulty service interactions. Most real-world applications make an attempt to recover gracefully from such errors by retrying the piece of work that failed, taking care to roll it back first. If the probability of the error reoccurring is low, then chances are that the application will be able to move forward. To facilitate this type of behavior in WS-BPEL, we introduce the notion of atomicity that (a) guarantees all-or-nothing semantics (b) induces rollback-and-retry on transient errors and (c) induces rollback-and-fault on persistent errors.
We define atomicity in terms of the "atomic" extension attribute (marked "yes"), which may be applied on the following WS-BPEL elements:
a) The <process> element, which denotes the top-most unit-of-work, and has an implicit scope of its own. If the process starts with an inbound message activity, then in case of a rollback, the process will block until a new message is received.
b) The <scope> element, which denotes a fine-grained unit-of-work and provides the context for its enclosed activity. If the scope starts with an inbound message activity, then in case of a rollback, the scope will block until a new message is received.
c) The <onEvent> element, which denotes a concurrent unit-of-work and is triggered by an inbound message. Note that its atomicity is independent of that of its enclosing scope. Also, while the child within an event handler is always a <scope> activity, making that atomic will not cause the process to block until a new event arrives.
Note that in order to achieve the all-or-nothing behavior, we must begin, commit or rollback a JTA global transaction when the execution of an atomic element starts, succeeds or fails, respectively. In addition, we implicitly commit the process when it hits a blocking activity, such as a receive. Consequently, we disallow the use of a <receive> activity anywhere inside an atomic activity, except as its first basic activity. A healthy side-effect of this constraint is that it frees us from deadlocks that might otherwise arise due to circular service interactions.
The retry logic of atomic activities may be configured using the following two configuration properties:
a) scopes.atomic.retry.count: This number indicates the number of times the atomic activity will be "retried" before it gives up, which defaults to 3. Specifically, it may be executed at most one more time than this count. Strictly speaking, the first attempt at executing the atomic activity is not considered to be a "retry".
b) scopes.atomic.retry.delay: This number indicates the number of seconds the process will wait before "retrying" a previously failed atomic activity, which defaults to one minute.
If the atomic activity successfully completes during its first try or one of its subsequent retries, the process will proceed to the following activity, as it normally would have. If the atomic activity repeatedly fails and the allowed number of retries is exceeded (i.e., the error is no longer transient, but rather persistent), it will in turn throw a ode:scopeRollback fault, which may be caught and handled by one of its enclosing scopes (or not).
Let us now discuss the rollback aspect of an atomic activity. In the event of a failure, before we retry it, we will revert the state of the process back to the point when it was just about to commence execution. As a result, we discard any change to the process state caused by copy operation assignments, message activity variable and correlation initialization, link status evaluations, and so on. Furthermore, one-way messages meant to be sent on success are discarded and two-way messages already sent have the consumed service rolled back. Speaking of two-way messages, we limit the scope of our initial implementation to message exchanges with processes and services that co-exist in the same server (node). Supporting atomicity across external services would require the use of a web service transaction protocol such as WS-AtomicTransaction, but that standard is neither specified nor implemented fully.
For more details, please refer to http://ode.apache.org/atomic-scopes-extension-for-bpel.html.