You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ode.apache.org by Karthick Sankarachary <sa...@intalio.com> on 2008/09/29 23:33:23 UTC

Atomic Scopes

Just a few quick observations on the atomic
scopes<http://ode.apache.org/atomic-scopes-extension-for-bpel.html>
 spec:

a)  The state of a scope consists of not just its variables but also its
correlation sets. So, just like assigns are collectively atomic, correlation
sets must be collectively atomic too. The easiest way to implement this
would be to take a checkpoint of all variable and correlation state when the
atomic scope begins, so that if anything should go wrong, we simply rollback
to that checkpoint.

b) The spec doesn't say how atomic scopes should be retried in the case of
faults. Apparently, there already exists a fault &
recovery<http://ode.apache.org/activity-failure-and-recovery.html>
spec
that addresses retries. To use that feature, I suggest replacing the
atomic:scopeRollback fault with the ext:activityFailure fault. In
particular, if a two-way invoke inside an atomic scope fails due to a
distributed rollback or some other invoke-specific fault, then it should
throw an ext:activityFailure, which is caught and retried in the
<ext:failureHandling> element defined for the atomic scope. In addition, we
should extend the failure mechanism to the other message activities, such as
receive and reply, so that they too are able to trigger the retry mechanism
in an atomic scope.

c) In section 4, the spec says that the receive/reply must not cross the
boundary of the atomic scope. However, this is not really a new requirement,
since the standard already says that a bpel:missingReply be thrown in such
cases.

d) Is there a reason why we can't propagate the transaction context in
one-way invokes? The spec contradicts itself by saying that "one-way
receives doesn't use a distributed transaction protocol" (in section 7.2),
and stating that "an atomic scope that begins by receiving a message using a
distributed transaction protocol must enroll in the transaction and
participate in determining the outcome of that transaction" (in section
7.1). Personally, I think that both one-way receives and one-way invokes
should propagate the transaction context, if at all possible. In the case of
one-way invokes, we should try to send the message right away along with the
context, and perform a 2-phase commit with the invoked service when the
scope ends. If the transaction context cannot be propagated, then we should
wait for the atomic scope to end before sending the message. Similarly, in
the case of one-way receives, if the incoming message contains a transaction
context, then we consume the message (from our internal queue) right away.
If no context was sent, then we consume the message only if the atomic scope
completes, because the partner will not re-send it.

e) In addition to intermediate one-way invokes, we should allow intermediate
one-way receives too. I understand the need to keep atomic scopes
short-running, but there may be cases where you may want an intermediate
receive to be part of the atomic transaction. If the message sent to a
one-way receive has a transaction context, then the atomic scope joins with
the partner's transaction. When the atomic scope ends, we first prepare all
global transactions, and commit all transactions only if all the prepares
were successful. To ensure that such atomic scopes don't run forever, the
user should be able to optionally set a transaction timeout.

f) What kinds of distributed transaction protocols do we want to support?
There's a Axis2-based implementation of WS-AtomicTransaction called Kandula,
but that's only going to work for the Axis2 IL. What about the SCA and JBI
ILs? Alternatively, do we want to use JTA in the case of message activities
that are backed by a co-located resource, such as a database? The advantage
of JTA is that it is not IL-specific, but on the flip side, it is not a
generic solution.

Best Regards,
Karthick Sankarachary

Re: Atomic Scopes

Posted by Assaf Arkin <ar...@intalio.com>.
On Tue, Sep 30, 2008 at 4:18 PM, Karthick Sankarachary
<sa...@intalio.com> wrote:
>>
>> >> > d) Is there a reason why we can't propagate the transaction context in
>>  >> > one-way invokes?
>> >>
>> >> Because we're treating two-way as synchronous and one-way as
>> >> asynchronous (different from request with empty response).  Applying
>> >> these constraints makes it easier to reason about, and pick which MEP
>> >> to use where.  Asynchronous messaging does not propagate atomic
>> >> transaction from sender & receiver.
>> >
>>
>
> Let me play devil's advocate here. Yes, one-way MEPs are typically used for
> asynchronous messaging. In particular, it makes sense to apply that
> constraint when the sending & receiving partners are decoupled from each
> other. However, we cannot rule out scenarios where two or more partners
> exchange one-way messages in such a way as to form a cycle, thereby
> forcing synchronization.

Of course I can, because now we're up one layer in the protocol stack,
the BPEL layer MEP, but the WSDL layer MEPs where transactions happen
are still all asynchronous.


> For example, let's consider a process P1 that sends
> a message to process P2, which sends a message to process P3, which in turn
> sends a message back to process P1. The only way to make such a choreography
> of one-way messages atomic is to propagate transactions in them.

You've just described the classical diamond scenario that
transactional systems work hard to avoid.

>
>
>>
>> >
>> >
>> > What happens the sender of the message consumed by the receive rollbacks?
>>
>> In asynchronous messaging, the sender transaction must complete before
>> the message becomes visible to the receiver; if the sender transaction
>> rolled back, there's no message for the receiver to process.
>>
>> If the sender and receiver were somehow tied to the same transaction,
>> they're now synchronized, we're talking about synchronous not
>> asynchronous messaging.  It's the one point of distinction most people
>> get wrong initially, and one reason why life is easier when you can
>> clearly identify synchronous and asynchronous patterns.
>>
>> Assaf
>>
>
> If we assume that one-way MEPs are asynchronous, then I agree that the
> sender and receiver must act as if they are unaware of each other. This
> constraint makes sense particularly if the underlying transport is JMS,
> where the two partners may be separated in time by a broker.
>
> What if we assume that one-way MEPs are asynchronous if and only if the
> exchange doesn't propagate the transaction context? If a context is present,
> then I think we are obligated to join the partner's transaction.

If a context is present, you're going to use it to queue the outgoing
message so it doesn't get transmitted unless the transaction commits,
and in doing do guarantee the ACID properties of the transaction.  But
because it doesn't get transmitted until after (and only if) the
transaction commits, it can't communicate the transaction context.  It
does, however, use the transaction context effectively to guarantee
the ACID properties.

Assaf

Re: Atomic Scopes

Posted by Karthick Sankarachary <sa...@intalio.com>.
>
> >> > d) Is there a reason why we can't propagate the transaction context in
>  >> > one-way invokes?
> >>
> >> Because we're treating two-way as synchronous and one-way as
> >> asynchronous (different from request with empty response).  Applying
> >> these constraints makes it easier to reason about, and pick which MEP
> >> to use where.  Asynchronous messaging does not propagate atomic
> >> transaction from sender & receiver.
> >
>

Let me play devil's advocate here. Yes, one-way MEPs are typically used for
asynchronous messaging. In particular, it makes sense to apply that
constraint when the sending & receiving partners are decoupled from each
other. However, we cannot rule out scenarios where two or more partners
exchange one-way messages in such a way as to form a cycle, thereby
forcing synchronization. For example, let's consider a process P1 that sends
a message to process P2, which sends a message to process P3, which in turn
sends a message back to process P1. The only way to make such a choreography
of one-way messages atomic is to propagate transactions in them.


>
> >
> >
> > What happens the sender of the message consumed by the receive rollbacks?
>
> In asynchronous messaging, the sender transaction must complete before
> the message becomes visible to the receiver; if the sender transaction
> rolled back, there's no message for the receiver to process.
>
> If the sender and receiver were somehow tied to the same transaction,
> they're now synchronized, we're talking about synchronous not
> asynchronous messaging.  It's the one point of distinction most people
> get wrong initially, and one reason why life is easier when you can
> clearly identify synchronous and asynchronous patterns.
>
> Assaf
>

If we assume that one-way MEPs are asynchronous, then I agree that the
sender and receiver must act as if they are unaware of each other. This
constraint makes sense particularly if the underlying transport is JMS,
where the two partners may be separated in time by a broker.

What if we assume that one-way MEPs are asynchronous if and only if the
exchange doesn't propagate the transaction context? If a context is present,
then I think we are obligated to join the partner's transaction.

Re: Atomic Scopes

Posted by Assaf Arkin <ar...@intalio.com>.
On Mon, Sep 29, 2008 at 3:46 PM, Karthick Sankarachary
<sa...@intalio.com> wrote:
>>
>> > b) The spec doesn't say how atomic scopes should be retried in the case
>> of
>> > faults.
>>
>> By repeating the activity.
>
>
> Does that mean that we have to redefine the <ext:retryFor> and
> <ext:retryDelay> options for the atomic scope activity?

Only if people have problem with these two being specified globally
and need to exert more control.


>> Due to their semantics, activity failure & recovery and atomic scope
>> are mutually exclusive and not intent to be used together.
>
>
> The only reason we would want to retry an atomic scope is because one of
> child activities fails due to a transient problem. Isn't that the same
> problem that the activity failure & recovery spec tries to address?

It's precisely that they intersect in some way, but are totally
different constructs designed primarily to support different use
cases, that makes them mutually exclusive.  They are both mechanisms
for error handling and recovery, and keeping them separate makes it
easier to reason about and properly use each one.


>> > d) Is there a reason why we can't propagate the transaction context in
>> > one-way invokes?
>>
>> Because we're treating two-way as synchronous and one-way as
>> asynchronous (different from request with empty response).  Applying
>> these constraints makes it easier to reason about, and pick which MEP
>> to use where.  Asynchronous messaging does not propagate atomic
>> transaction from sender & receiver.
>
>
> Does WS-AtomicTransaction disallow atomic transactions for one-way
> exchanges?

Do we care?  Constraints are a really good thing, and this is one
place that makes life really easy.  There's a lot to gain from
applying constraints and pattern semantics on the operation, ahead of
when the bindings are known.  This does not preclude you from doing
request/empty-response, but makes a clear separation between blocking
and non.


>> > The spec contradicts itself by saying that "one-way
>> > receives doesn't use a distributed transaction protocol" (in section
>> 7.2),
>>
>> However, the transaction context can propagate to/from the transport
>> mechanism, e.g. storing the message in a queue, retrieving the message
>> from a queue.  We definitely support propagation of the transaction
>> context to/from the transport.  In accepting the context on receive,
>> you can make sure the message is consumed only if the transaction
>> commits.
>
>
> What happens the sender of the message consumed by the receive rollbacks?

In asynchronous messaging, the sender transaction must complete before
the message becomes visible to the receiver; if the sender transaction
rolled back, there's no message for the receiver to process.

If the sender and receiver were somehow tied to the same transaction,
they're now synchronized, we're talking about synchronous not
asynchronous messaging.  It's the one point of distinction most people
get wrong initially, and one reason why life is easier when you can
clearly identify synchronous and asynchronous patterns.


>  Don't we want to be able to rollback the process that received that
> message, even though it is prepared to commit?
>
>> > e) In addition to intermediate one-way invokes, we should allow
>> intermediate
>> > one-way receives too. I understand the need to keep atomic scopes
>> > short-running,
>>
>> We do want to make them short and that's an easy constraint to apply
>> to the process definition.  Discouraging long-running atomic scopes by
>> making them harder to realize is a goal of the spec, not incidental.
>>
>
> In my opinion, the transaction timeout mechanism gives us the best of both
> worlds. It gives you a way to write short-running processes with
> intermediate receives.

Again, the point of the spec is to pick the best practice and
encourage it, while discouraging other behaviors or leaving them to
more courageous implementations (say, Java code).

Assaf

>
> Best Regards,
> Karthick Sankarachary
>

Re: Atomic Scopes

Posted by Karthick Sankarachary <sa...@intalio.com>.
>
> > b) The spec doesn't say how atomic scopes should be retried in the case
> of
> > faults.
>
> By repeating the activity.


Does that mean that we have to redefine the <ext:retryFor> and
<ext:retryDelay> options for the atomic scope activity?

>
> Due to their semantics, activity failure & recovery and atomic scope
> are mutually exclusive and not intent to be used together.


The only reason we would want to retry an atomic scope is because one of
child activities fails due to a transient problem. Isn't that the same
problem that the activity failure & recovery spec tries to address?


> > d) Is there a reason why we can't propagate the transaction context in
> > one-way invokes?
>
> Because we're treating two-way as synchronous and one-way as
> asynchronous (different from request with empty response).  Applying
> these constraints makes it easier to reason about, and pick which MEP
> to use where.  Asynchronous messaging does not propagate atomic
> transaction from sender & receiver.


Does WS-AtomicTransaction disallow atomic transactions for one-way
exchanges?

>
> > The spec contradicts itself by saying that "one-way
> > receives doesn't use a distributed transaction protocol" (in section
> 7.2),
>
> However, the transaction context can propagate to/from the transport
> mechanism, e.g. storing the message in a queue, retrieving the message
> from a queue.  We definitely support propagation of the transaction
> context to/from the transport.  In accepting the context on receive,
> you can make sure the message is consumed only if the transaction
> commits.


What happens the sender of the message consumed by the receive rollbacks?
 Don't we want to be able to rollback the process that received that
message, even though it is prepared to commit?


> > e) In addition to intermediate one-way invokes, we should allow
> intermediate
> > one-way receives too. I understand the need to keep atomic scopes
> > short-running,
>
> We do want to make them short and that's an easy constraint to apply
> to the process definition.  Discouraging long-running atomic scopes by
> making them harder to realize is a goal of the spec, not incidental.
>

In my opinion, the transaction timeout mechanism gives us the best of both
worlds. It gives you a way to write short-running processes with
intermediate receives.

Best Regards,
Karthick Sankarachary

Re: Atomic Scopes

Posted by Assaf Arkin <ar...@intalio.com>.
On Mon, Sep 29, 2008 at 2:33 PM, Karthick Sankarachary
<sa...@intalio.com> wrote:
> Just a few quick observations on the atomic
> scopes<http://ode.apache.org/atomic-scopes-extension-for-bpel.html>
>  spec:
>
> a)  The state of a scope consists of not just its variables but also its
> correlation sets. So, just like assigns are collectively atomic, correlation
> sets must be collectively atomic too. The easiest way to implement this
> would be to take a checkpoint of all variable and correlation state when the
> atomic scope begins, so that if anything should go wrong, we simply rollback
> to that checkpoint.

Conceptually, if the scope fails it's as if the scope never happened,
so the easiest implementation is to mark the transaction for rollback,
not store any changes, and evict the instance from memory.


> b) The spec doesn't say how atomic scopes should be retried in the case of
> faults.

By repeating the activity.

> Apparently, there already exists a fault &
> recovery<http://ode.apache.org/activity-failure-and-recovery.html>
> spec
> that addresses retries. To use that feature, I suggest replacing the
> atomic:scopeRollback fault with the ext:activityFailure fault. In
> particular, if a two-way invoke inside an atomic scope fails due to a
> distributed rollback or some other invoke-specific fault, then it should
> throw an ext:activityFailure, which is caught and retried in the
> <ext:failureHandling> element defined for the atomic scope. In addition, we
> should extend the failure mechanism to the other message activities, such as
> receive and reply, so that they too are able to trigger the retry mechanism
> in an atomic scope.

If the atomic scope fails, it's as if the scope never happened, in
which case we can just retry it again.  Eventually we have to give up,
and communicate that to the enclosing scope.  The enclosing scope can
tell what happens because it receives the scopeRollback fault.

Due to their semantics, activity failure & recovery and atomic scope
are mutually exclusive and not intent to be used together.


> c) In section 4, the spec says that the receive/reply must not cross the
> boundary of the atomic scope. However, this is not really a new requirement,
> since the standard already says that a bpel:missingReply be thrown in such
> cases.

Not new, but it doesn't cost us to elaborate on restrictions.


> d) Is there a reason why we can't propagate the transaction context in
> one-way invokes?

Because we're treating two-way as synchronous and one-way as
asynchronous (different from request with empty response).  Applying
these constraints makes it easier to reason about, and pick which MEP
to use where.  Asynchronous messaging does not propagate atomic
transaction from sender & receiver.


> The spec contradicts itself by saying that "one-way
> receives doesn't use a distributed transaction protocol" (in section 7.2),

However, the transaction context can propagate to/from the transport
mechanism, e.g. storing the message in a queue, retrieving the message
from a queue.  We definitely support propagation of the transaction
context to/from the transport.  In accepting the context on receive,
you can make sure the message is consumed only if the transaction
commits.


> and stating that "an atomic scope that begins by receiving a message using a
> distributed transaction protocol must enroll in the transaction and
> participate in determining the outcome of that transaction" (in section
> 7.1). Personally, I think that both one-way receives and one-way invokes
> should propagate the transaction context, if at all possible. In the case of
> one-way invokes, we should try to send the message right away along with the
> context, and perform a 2-phase commit with the invoked service when the
> scope ends. If the transaction context cannot be propagated, then we should
> wait for the atomic scope to end before sending the message. Similarly, in
> the case of one-way receives, if the incoming message contains a transaction
> context, then we consume the message (from our internal queue) right away.
> If no context was sent, then we consume the message only if the atomic scope
> completes, because the partner will not re-send it.
>
> e) In addition to intermediate one-way invokes, we should allow intermediate
> one-way receives too. I understand the need to keep atomic scopes
> short-running,

We do want to make them short and that's an easy constraint to apply
to the process definition.  Discouraging long-running atomic scopes by
making them harder to realize is a goal of the spec, not incidental.


> but there may be cases where you may want an intermediate
> receive to be part of the atomic transaction. If the message sent to a
> one-way receive has a transaction context, then the atomic scope joins with
> the partner's transaction. When the atomic scope ends, we first prepare all
> global transactions, and commit all transactions only if all the prepares
> were successful. To ensure that such atomic scopes don't run forever, the
> user should be able to optionally set a transaction timeout.
>
> f) What kinds of distributed transaction protocols do we want to support?

2PC.

> There's a Axis2-based implementation of WS-AtomicTransaction called Kandula,
> but that's only going to work for the Axis2 IL. What about the SCA and JBI
> ILs? Alternatively, do we want to use JTA in the case of message activities
> that are backed by a co-located resource, such as a database? The advantage
> of JTA is that it is not IL-specific, but on the flip side, it is not a
> generic solution.

Note that JTA is an API, not a protocol.  The resource manager
enlisted under JTA may use all sort of protocols, we don't have to be
aware of or list them.

Assaf

>
> Best Regards,
> Karthick Sankarachary
>