OpenEmcee Microflow Engine for Java

Home | Downloads | Project Information | Discussion Groups | Tutorials | Team

Documentation

Tutorials
JavaDoc
News

FAQ's

Lists/Support
Strange name?

Downloads

Downloads
CVS Access

 

 

 

 

 

 

 

 

 

 

 

 

Pseudo-Transaction Management with OpenEmcee Microflows (Beta - Unedited)

By Scott Schenkein

Software systems often have complicated error-handling requirements. Implementation of these requirements can often lead to code that is difficult to understand and maintain. The OpenEmcee Microflows "undo" mechanism is designed to provide a consistent way to handle "pseudo-rollback" of previously completed work when an error occurs.

A common solution to this issue is a simple database rollback. As some systems are not purely implemented using database (or other XA compliant) transactions, special work must be done to back-out changes made during business processing.

The Business Case

Consider a simple airline reservation system with the following requirements.

When booking a flight, the system must:

1. Reserve the flight with the airline.
*If any part of this process fails, this reservation must be backed out.

2. Update the customer's profile to denote that they reserved this flight.
* If any part of the process fails, the customers account must be returned to its previous state.

3. Authorize the flight amount on the customer's credit card.

4. Update the reservation database with the credit authorization information.

Solutions, solutions…

This problem could be approached in several ways, for example:

  1. Manually keep track of what has happened, and then write code to undo work at every possible failure point. This might become broken when new requirements are introduced into the system.
  2. Create transactional EJB's which use the javax.ejb.SessionSynchronization interface to detect a rollback, and implement the custom rollback logic for the non-database error-handling requirements (see requirement 1, 2 would be handled by normal database rollback). Consider that this solution couples the error handling with the core processing.
  3. Use OpenEmcee "undos". (12/12/2003) Note that an EJB implementation, which integrates OpenEmcee Microflows and its "Undo" functionality into Java enterprise-transactions will soon be available.

Lets Choose Step 3 (I bet you didn't see that coming)

An OpenEmcee Microflow task definition can include two different tasks. One is the business task, and one is the undo. Undos are optional and business tasks are required.

All undos (for tasks which successfully executed) will be invoked if the Microflow terminates with a failure (Additionally when the EJB implementation is available, the undos will be called if the EJB transaction rolls back.):

<task name=…
     <outcome name="whatever" terminal="true" failure="true"/>
</task>

The implementation of an undo task is identical to that of a business task. Simply create a class which implements the "org.openemcee.microflow.usercore.MicroflowTask" interface, implementing your back-out (undo) logic in the "executeTask" method. For a review of how to implement a MicroflowTask, please see the OpenEmcee Intro.

Associating an Undo with a Task

Please see the following job-descriptor snippet for an example of how we associate the undo. Inline comments should provide commentary.

<!-- Begin the Microflow by Reserving the ticket. -->
<first-task>ReserveTicket</first-task>

<!-- Reserve the ticket, if the flow fails,
     the UnreserveTicket task will be called. -->


<task name="ReserveTicket"
    jclass="com.airline.ReserveTicketTask"
    undoJclass="com.airline.UnreserveTicketTask">
         <outcome name="success"
                  nextTask="UpdateCustomerProfile"/>
         <outcome name="failure"
                  terminal=”true”
                  failure=”true”/> <!-- Failure is true, terminate, and
                                        call any pending “undos”. -->

</task>

<!-- Update the customer profile, if the flow fails,
     the RestoreCustomerProfile task will be called. -->

<task name="UpdateCustomerProfile"
    jclass="com.airline.UpdateCustomerProfile"
    undoJclass="com.airline.RestoreCustomerProfile">
         <outcome name="success"
                  nextTask="ProcessCredit"/>
         <outcome name="failure"
                  terminal=”true”
                  failure=”true”/>
</task>

<task name="ProcessCredit"
    jclass="com.airline.ProcessCredit”>
         <outcome name="success"
                  nextTask="UpdateReservationDB"/>
         <outcome name="failure"
                  terminal=”true”
                  failure=”true”/>
</task>

<task name="UpdateReservationDB"
    jclass="com.airline.UpdateReservationDatabase”>
         <outcome name="success"
                  terminal=”true”
                  failure=”false”/> <!--False is the default value -->
         <outcome name="failure"
                  terminal=”true”
                  failure=”true”/>
</task>


Some Sample Executions

1. In the case where all steps complete successfully, none of the undos will execute.
2. In a case where "ReserveTicket" succeeds, but "UpdateCustomerProfile" fails

  • The "UnreserveTicketTask" is executed.
  • "RestoreCustomerProfileTask" is not called because "UpdateCustomerProfile" never successfully completed.

3. In a case where all steps complete successfully except for the final "update reservations DB":

  • The "RestoreCustomerProfileTask" is executed.
  • The "UnreserveTicketTask" is executed.
  • Note that the undos are executed in the opposite order to which their respective business tasks were executed. (Undo's are stored in a stack).

Some Limitations to Note

At the time of this documents writing (12/12/2003), the following limitations effect the "undo" facility.

  1. There is no facility for handling failures of Microflow undo tasks.
  2. There is no facility for passing parameters to Microflow undo tasks. If the OpenEmcee Microflow community expresses an interest in this functionality, it will be added to the system.

If the OpenEmcee Microflow community expresses an interest in this functionality, it will be added to the system.

What we have learned

In this installment, we have learned how to separate complex error handling from core business processing. This facility can prove useful in creating systems with complex error-handling requirements that are easily understandable and maintainable.

 
 

SourceForge.net Logo