TransactionScopeActivity


In the WF programming model, the idea is to adopt the same simple model shown previously for TRansactionScope. WF, like System.Transactions, uses the term transaction to always mean an ACID (Atomic, Consistent, Isolated, and Durable) transaction. Concepts such as long-running transactions (not a term that is used within the WF programming model) are accommodated by WF programming model features such as activity compensation (which was discussed in Chapter 4, "Advanced Activity Execution").

In this book, when we refer to transactions, we always mean ACID transactions.

System.Workflow.ComponentModel.TransactionScopeActivity is a composite activity that, when used within a WF program, behaves much like a (System.Transactions) transactionScope in a C# program. transaction-ScopeActivity is the root of a subtree of activities that all take part in the same transaction:

 <wf:TransactionScopeActivity>   <Sequence>     ...   </Sequence> </wf:TransactionScopeActivity> 


If an activity contained at any depth within a transactionScopeActivity uses a resource manager in its execution logic, the resource manager automatically enlists in the ambient transaction. An activity that updates customer information in a database table might therefore look something like this:

 using System; using System.Workflow.ComponentModel; using System.Workflow.ComponentModel.Compiler; namespace EssentialWF.Activities {   public class UpdateCustomerInfo : Activity   {     ...     protected override ActivityExecutionStatus Execute(       ActivityExecutionContext context)     {       using (System.Data.SqlClient.SqlConnection conn =         new System.Data.SqlClient.SqlConnection(...))       {         // update database tables       }       return ActivityExecutionStatus.Closed;     }   } } 


TRansactionScopeActivity behaves in a WF program very much like a declarative variant of TRansactionScope, so the execution logic of UpdateCustomerInfo does not need to create a TRansactionScope objectwhen the UpdateCustomerInfo activity executes, an ambient transaction will be present, courtesy of transactionScopeActivity.

As an activity writer, we may wish to stipulate that an activity like Update-CustomerInfo should only be used within a transactionScopeActivity. To do this, we need to write validation logic (a topic covered in more detail in Chapter 7, "Advanced Authoring") for UpdateCustomerInfo that ensures an Update-CustomerInfo activity is always nested (at some depth) within a transactionScopeActivity:

 using System; using System.Workflow.ComponentModel; using System.Workflow.ComponentModel.Compiler; namespace EssentialWF.Activities {   [ActivityValidator(typeof(UpdateCustomerInfoValidator))]   public class UpdateCustomerInfo : Activity   {     ...   }   public class UpdateCustomerInfoValidator: ActivityValidator   {     public override ValidationErrorCollection Validate(       ValidationManager manager, object obj)     {       ValidationErrorCollection errors =         base.Validate(manager, obj);       UpdateCustomerInfo activity = obj as UpdateCustomerInfo;       CompositeActivity parent = activity.Parent;       bool ok = false;       while (parent != null)       {         if (parent is TransactionScopeActivity)         {           ok = true;           break;         }         parent = parent.Parent;       }       if (!ok)         errors.Add(new ValidationError("UpdateCustomerInfo must be nested within a TransactionScopeActivity", 1000));       return errors;     } } } 


The transactionScopeActivity type is shown in Listing 6.1.

Listing 6.1. transactionScopeActivity

 namespace System.Workflow.ComponentModel {   public sealed class TransactionScopeActivity     : CompositeActivity   {     public WorkflowTransactionOptions TransactionOptions       { get; set; }     /* *** other members *** */   } } 


Just as you can for a System.Transactions.TransactionScope, you can set the isolation level and the timeout that are to be used for the transaction that is created by a transactionScopeActivity. The TRansactionScopeActivity.TransactionOptions property, of type System.Workflow.ComponentModel.WorkflowTransactionOptions, is the place where these options are specified.

The WorkflowTransactionOptions type is shown in Listing 6.2.

Listing 6.2. WorkflowTransactionOptions

 namespace System.Workflow.ComponentModel {   public sealed class WorkflowTransactionOptions     : DependencyObject   {     public System.Transactions.IsolationLevel IsolationLevel       { get; set; }     public System.TimeSpan TimeoutDuration { get; set; }     /* *** other members *** */   } } 


Assignment of transactionScopeActivity.TransactionOptions will appear in XAML like so:

   <wf:TransactionScopeActivity>     <wf:TransactionScopeActivity.TransactionOptions>       <wf:WorkflowTransactionOptions TimeoutDuration="00:01:00" IsolationLevel="Serializable" />       </wf:TransactionScopeActivity.TransactionOptions>       <Sequence>       ...     </Sequence>   </wf:TransactionScopeActivity> 


In the preceding XAML snippet, a timeout of one minute has been set for the transaction, and the isolation level is System.Transactions.IsolationLevel.Serializable.

Within a WF program instance, when a transactionScopeActivity begins its execution, only activities inside the transactionScopeActivity will be allowed to execute until the transactionScopeActivity completes. This is enforced by the WF runtime. Doing this ensures the consistency of data within the WF program by effectively serializing the execution of transactionScopeActivity with respect to the rest of the activities in the WF program instance. Furthermore, during the execution of a TRansactionScopeActivity, the WF program instance will not be allowed to persist or passivate (after all, a transaction is in progress).

To guarantee all-or-nothing semantics with respect to WF program instance state, transactionScopeActivity takes a snapshot of the program instance state just before it creates a transaction. If an unhandled exception occurs (during the subsequent execution of its child activities), causing a transactionScopeActivity to move to the Faulting state, the instance state snapshot is used by TRansactionScopeActivity to revert the state of the WF program instance before the transaction is rolled back. The exception then propagates up the activity tree of the WF program.

TransactionScopeActivity Validation

transactionScopeActivity has a custom validator component that imposes a few restrictions on its usage in WF programs.

Nesting of transactionScope objects is allowed by System.Transactions. But in the WF programming model, you cannot nest a transactionScopeActivity within another transactionScopeActivity. This limitation precludes certain advanced scenarios; it is not unreasonable to expect the WF programming model to improve in this area in the future.

A transactionScopeActivity in a WF program cannot have fault handlers. The point of a transaction is that its work either succeeds or fails. There is no such thing, in transaction programming, as a "failed, but successfully handled the exception" outcome for a transaction. That is why a composite activity that contains a transactionScopeActivity can handle a transaction-related exception, but the transactionScopeActivity itself cannotit either succeeds or fails.

A transactionScopeActivity in a WF program also cannot have a cancellation handler. Again, the point of a transaction is that its work either succeeds or fails. As all-or-nothing operations, transactions by definition do not need to support cancellation logic (which, in WF programs, is only invoked for a partially completed activity).

The WF runtime will not allow suspension of a WF program instance while a transaction is in progress. Consequently, the validation logic of SuspendActivity (discussed in Chapter 5, "Applications") will not allow the presence of Suspend-Activity, at any depth, within a transactionScopeActivity. Similarly, the WF runtime will not allow termination of a WF program instance while a transaction is in progress. The validation logic of TerminateActivity (also discussed in Chapter 5) will not allow the presence of TerminateActivity, at any depth, within a TRansactionScopeActivity.




Essential Windows Workflow Foundation
Essential Windows Workflow Foundation
ISBN: 0321399838
EAN: 2147483647
Year: 2006
Pages: 97

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net