Re: Co-ordination protocol and BPEL

Assaf,

Can you confirm my understanding from your previous message ?

When a caller invoke a service (which is implemented in BPEL using 
<receive>) and pass-in a transaction context.  The caller will receive a 
SOAP fault if any of the following happens ....
a) The <receive> is NOT defined within a <scope>
b) The <receive> is NOT the first activity of that <scope> AND some 
"different" context has already been established.  (e.g.  There is an 
<invoke> preceding this <receive>, or there is another <receive> preceding 
this <receive>)

Best regards,
Ricky

>Ricky Ho wrote:
>
>>
>>There are a couple of issues ....
>>
>>Lets say in the following process
>>
>><process>
>>   <sequence>
>>     ....
>>     <receive/>
>>     ....
>>     <reply/>
>>     ....
>>     <receive/>
>>     ....
>>     <reply/>
>>     ....
>>   </sequence>
>></process>
>>
>>1) Lets say the first <receive> pass in a transaction context.  What is 
>>the "scope of work" ?  Between the first request and first reply ?
>>or everything after the first receive ?
>
>That depends on how you define the importing of the context.
>
>If you define the scope as the entire sequence then it will start with the 
>first receive but it will end all the work after the last activity has 
>occurred (i.e. after the second reply). The sender is not just waiting for 
>a reply, the sender is also waiting to later on either receive a 
>completed, exited, or failed message indicating that all further work done 
>after the reply has completed/failed.
>
>If the scope is for a single activity than only that activity is 
>performed, but again after the reply is sent you still need to send 
>completed/exited/failed which you could potentially piggyback on the reply 
>message (though not allowed in WS-TX currently).
>
>
>>2) Lets say after receiving the first <reply>, the caller want to commit 
>>the transaction.  What scope of work has been committed ?  Does the 
>>caller wait for this whole process to be completed before the caller's 
>>transaction can commit successfully ?
>
>If we are talking BA then there are two modes: either you tell the process 
>when all work has been completed so it can wrap up things on its side and 
>send a completed/exited message, or you wait for it to tell you when it 
>completes and then wait for all others to tell you they completed. In case 
>of aborting, you would just tell working scopes to cancel and completed 
>scopes to compensate.
>
>The important thing here is that you should say what you mean and mean 
>what you say. If what you meant is that no work could be completed unless 
>you received two requests, then that's what should happen. If someone 
>tries to commit before you completed all the work you consider this to be 
>an inconsistent state and vote to rollback. This means that you will never 
>do part of the work - either all or nothing.
>
>If what you meant is that only some work needs to be done and the rest is 
>optional, you should write it as such, perhaps by using an event handler.
>
>
>>3) If instead the caller want to cancel the transaction.  How does the 
>>process cancel its work ?  Where is the compensation handler defined ?
>
>Since you haven't yet completed the sequence you can't compensate for it. 
>Instead you get a terminate fault and handle it. However, since you 
>already did some activities you may have nested scopes with their own 
>compensation handlers which you would invoke from the event handler of the 
>sequence.
>
>
>>4) What if the second <receive> pass in a different context ?  (the only 
>>way to prevent this happening is to use the context itself as the 
>>correlation set)
>
>Good question.
>
>In EJB if you have a session bean and you call it twice in two different 
>transactions then the access would be serialized or you would get an 
>error. I don't exactly remember which case is true, but you won't get two 
>invocations from two transactions for the same bean if one transaction has 
>not completed yet.
>
>So I would tend to believe that the rule should be that all incoming 
>messages should either be part of the same scope, part of a child scope 
>(if that activity is defined as part of a child scope), or not associated 
>with any scope. But it can't be part of a different scope unless it 
>observes a parent-child relationship.
>
>>>So it would work like the transaction attribute requires in an EJB bean. 
>>>Either you start a new transaction if none was started by the caller, or 
>>>you participate in the caller's transaction.
>>
>>
>>BPEL <Receive> is quite different from the EJB scenario.  The EJB doesn't 
>>have a pre-establish transaction context, it either starts a new context 
>>or inherit the caller's context.  In EJB, you never run into the 
>>situation of the above question 4.
>
>I think you do. If you think of a session bean, once you access it from a 
>transaction it is owned by that transaction until it commits. You can keep 
>calling it from that transaction, but you can't call it from another 
>transaction at the same time. That would just confuse the hell out of it ;-)
>
>The case here is of course more complex because you have more explicit 
>sequencing rules, a problem you also have with EJB but don't notice 
>because there is no language to write the behavior, and because you have 
>nesting.
>
>>>For atomic transactions you don't need prepare or commit, you are 
>>>working at a higher level than the code and all that needs to be 
>>>prepared or committed should be done by the engine for you. For BA 
>>>transactions you don't have prepare or commit, every response is an 
>>>indication that all previous steps have been completed (prepared and 
>>>committed). You do need a way to cancel, but this can be done by a fault 
>>>handler (the terminate fault). And you do need a way to compensate and 
>>>this is done by a compensation handler.
>>
>>
>>I'm talking about BA, not atomic.  Effectively, you restrict the choices 
>>by forcing every scope of work must be compensatable.
>
>>Lets say I'm an airline company.  I don't want to reserve the seat for a 
>>lengthy period and later cancel it when the passenger change his 
>>mind.  So my strategy is to only book the seat when the customer commits 
>>its purchase.  After that, I don't refund (so not compensatable from the 
>>passenger's perspective).
>>The original state of the seat is "available".  When the passenger invoke 
>>my "TicketBookingService", the seat is marked "potentially-booked".  When 
>>the transaction commit successfully, the seat status to be 
>>"booked".  After that, it is non-compensatable.
>>
>>How do I achieve this if I only have the CompensationHandler ?
>
>You have one activity (possibly a sequence) that changes the seat 
>assignment to "reserved". Afterwards it can be cancelled by the customer 
>or it can be cancelled because the customer did not send a booking request 
>within a well defined time frame (e.g. use a switch with message event and 
>time-out event). If it gets cancelled then you invoke the compensation of 
>the first activity changing it back to "available". If you do receive a 
>request to book the seat you proceed to the next step. At this point the 
>state is "booked" and there is no compensation associated with the 
>previous state.
>
>I think as a basic shell you would have to write something like:
>
>process
>  compensationHandler
>    empty
>    (note: very important to write something here so it doesn't
>     automatically compensate reserveToBook)
>
>   receive reservation request
>   scope name=reserveToBook
>     invoke name=reserve
>      compensationHandler
>       ... change back to available
>     ... this is where we talk to a service that changes state to reserved
>  pick
>     branch 1: booking request
>        change to booked
>     branch 2: alarm
>        throw a fault
>do anything else after reservation
>
>arkin
>
>>
>>
>>Rgds, Ricky
>
>
>
>--
>"Those who can, do; those who can't, make screenshots"
>
>

Received on Thursday, 22 May 2003 12:11:31 UTC