Flylib.com

Books Software

 
 
 

Transactional Delivery of Data


Transactional Delivery of Data

The previous section explored how the progress of a WF program instance, which unfolds episodically, is recorded using transactionsand, significantly, also how transaction-aware services utilized by activities can participate in these transactions. Essentially, what we learned boils down to a model for how WF program instances can send data to external systems in a transactional manner.

Now we can turn our attention to the inbound direction. How can data be handed from an external system to a WF program instance in a transactional manner? To answer this question, we return to the WorkflowInstance.EnqueueItem method that we introduced back in Chapter 3 for our ReadLine activity. The signature of this method is shown here:

public void EnqueueItem(IComparable queueName,
                        object item,
                        IPendingWork service,
                        object workItem);


The queueName parameter is the name of a WF program instance queue where the WF program instance is ready to receive data. A WF program instance queue is nothing more than the data structure used by a bookmarka named location where the execution of a WF program instance (or, more specifically , an activity within a WF program instance) can be resumed.

The item parameter is the data that is being enqueued.

When we used the EnqueueItem method in the code snippets of earlier chapters, we only used the first two parameters and passed a value of null for the other two. Now, though, you can guess that it is precisely these latter two parameters that give us the ability to enqueue data in a transactional manner.

When an item is enqueued into a WF program instance queue, it is available for processing by the WF program instance. However, just as we discussed earlier, the WF program instancethough it can consume this datamay not reach its next persistence point before some failure condition occurs.

If we pass null as the value of the latter two parameters of EnqueueItem , and a failure occurs before the next WF program instance persistence point, the enqueued data is lost. Instead, if we provide a transaction-aware service and a work item when we enqueue the data, our service will get called when the next persistence point in the WF program instance is reached. A transaction will then be available so that our service can transactionally record the fact that the data was successfully handed to the WF program instance.



Where are We?

In this chapter, we learned how WF program instances are executed in a durable and transactional manner. Because the execution progress of a WF program instance is recorded transactionally , it is possible to keep the state of the program consistent with the state of the external world, with which the program is interacting.

The transactionScopeActivity activity allows us to explicitly model transactional boundaries in a WF program. The transaction used by a transaction-ScopeActivity is the same transaction that is used to persist the WF program instance at the end of the execution of the transactionScopeActivity .

We saw how to write an activity that lets us declaratively specify persistence points in WF programs, and we were also reminded that a host application can initiate passivation (which entails persistence) at any time (except if a TRansactionScopeActivity is executing). Transactional services used by activities can participate in the transaction used for persistence, regardless of whether a transactionScopeActivity is employed in a WF program. And, external entities that enqueue items into WF program queues can also do work within the transaction that is used to persist the newly enqueued item as part of the WF program instance statein this way, we can achieve transaction handoff of data from external entities to WF program instances.