Working with CRUD activities – Short Transactions

XAF Team Blog
14 June 2011

In this post we are going to examine a workflow model that involves long operations. Our example will be based on the following concept which should be familiar from previous posts.

When working with workflows and persistent objects it is better to keep transactions short. For example, when reading data from a database, checking values, modifying, creating, deleting, committing changes and completing transactions. It is better to avoid continuous operations in the ObjectSpaceTransactionScope, because we are inside an XPO transaction. Since this is an atomic operation, workflow can not be persisted while workflow is inside the ObjectSpaceTransactionScope. If there is a need to use delays, especially within loops, consider placing them outside XAF’s container activities (NoPersistScope, ObjectSpaceTransactionScope).

Take this example, an issue is active after 4 hours and we need to notify the manager about it. We can use the WorkFlow MainDemo as a starting point for providing a solution to this scenario.

First we need to modify our issue class to provide creation time information. Adding a new DateTime property and initializing it after object construction fulfills this requirement.

image

Secondly we are going to create a new workflow definition at runtime and set the Target Object Type to Issue. At the same time we are going to check the Object Is Created without providing any criteria. These adjustments are enough for the workflow server services to start the workflow definition.

image

We are going to initiate the workflow model by retrieving the creation time from the Issue and storing it in a variable. There will be additional stages in this workflow, thus it is better to start with a Sequence activity that will function as a container and will help share variables between child activities.

image

The name of the Sequence activity has been changed to SequenceRoot. The reason is that it is not clear how many Sequence activities will be used and we want Scope to differentiate between them. Of course this is a matter of design preference and more confident developers may skip this step. issueCreateOn holds the creation time letting us move to the next step. The result is that we are able to use a Delay activity inside a DoWhile to periodically check if the 4hr time interval has passed. Alternatively we could follow similar approaches to model this. Using a small delay duration we could again calculate if the time interval has passed allowing us to inject behavior just after the Issue is closed. An example would be to sent an email that the Issue is not active any more.

image

In the above design the DoWhile activity cannot act as a container. Moreover since we haven’t implemented the workflow yet we have used a Sequence activity to fill this role. We have also parameterized the duration of the Delay activity with the maxCloseIssue variable. Finally we have used this variable to calculate when the time interval passed.

The design is not yet complete due to the fact that the DoWhile condition should include a check for whether a current issue is active. There will be a problem with the Delay activity at this point because the workflow will unload and persist to the database. In order to prevent this we need to query the issue again, after the Delay duration, to obtain its active property as in the first stage.

image

 

Finally we need to update the DoWhile condition with the isIssueActive constrain.

 

image

The following diagrams show the final stages of the workflow. All that remains is to create a task to notify the manager. We can use an If activity to check if the Issue is active then query the Issue again and create a new Task in order to achieve this.

image

There are cases however with complex conditions (see DoWhile condition above) or times when we want to get the values of variables or even see whether objects returned from activities like GetObjectsByCriteria are valid. In such cases we can use the debugger and initialize the targetObjectId argument with a valid value. We are then able to set the breakpoints we want and just hit run to see if our workflow execution is valid. The next video demonstrates the above and more

We would appreciate your feedback on this post. Has it been useful to you? Feel free to contact us  with any further questions.

Related Links
Videos in our TV channel
Online documentation
Blog posts

Free DevExpress Products - Get Your Copy Today

The following free DevExpress product offers remain available. Should you have any questions about the free offers below, please submit a ticket via the DevExpress Support Center at your convenience. We'll be happy to follow-up.
No Comments

Please login or register to post comments.