Persistence in learning WF (17): Compensation in Wf

Source: Internet
Author: User

Insist on learning WF Article Index

1. a transaction is not successful or failed when you make a group of updates. It is impossible to only partially update the transaction. The most typical application of transactions is in relational databases. Compensation is an operation that has been successfully canceled. In our workflow, we may complete a task consisting of many activities. For example, our activities all use transactionscopeactivity, and we will find an error later, if you want to cancel a successful operation, it has nothing to do with the transaction, because the transaction has been successful. In this case, we can use compensation. You can logically divide a group of activities and specify a compensation processor for this group of activities. In the compensation processor, you declare that if the compensation is successful, the group will be executed. The compensation processor automatically tracks exceptions. Or we can directly use compensateactivity.

The transaction can be rolled back automatically, but the compensation is not. The compensation only provides a place for you to cancel the work, but the specificCodeYou can implement it on your own. WF implements the icompensatableactivity interface, which can be compensated. WF provides two compensatabletransactionscopeactivity
, Compensatablesequenceactivity. The previous activity supports transactions and compensation. Compensatablehandleractivity is the container for your compensation. You can also explicitly use compensateactivity, which allows you to use its targetactivityname to specify compensation for an activity. However, this activity can only be added to compensationhandleactivity, faulthandleractivity, and cancellationhandleractivity.

Ii. Here is a specific example to illustrate if compensation is used. If you plan to travel, you will first set a train ticket before departure and then set a hotel. If you have set a train ticket, but when you decide a hotel, you will find that all the hotels have been booked by others. At this time, the train ticket you set is useless, I had to unsubscribe. In ourProgramWe use compensation to complete this function. Is the workflow we designed:

The procedure is as follows: first reserve a train ticket and then reserve a hotel. When booking a hotel, we will determine whether the ticket is successful. If it fails, an exception is thrown. The ticket booking activity (bookticket) is included in the compensatabletransactionscopeactivity activity. The compensation process is as follows:

When booking a hotel, if the reservation fails, we will use the bookfail (throwactivity) activity in to throw an exception. The following is a custom exception class. The Code is as follows:

 Using System; Using System. Collections. Generic; Using System. LINQ; Using System. text; Using System. runtime. serialization; Namespace Carycompensationdemo {[ Serializableattribute ()] Public class  Booktransaction exception : Exception { Public Book1_exception (): Base (){} Public Bookexcepexception ( String Message ): Base (Message ){} Public Bookexcepexception ( String Message,Exception Innerexception)
: Base (Message, innerexception ){} Protected Bookexcepexception ( Serializationinfo Info, Streamingcontext Context)
: Base (Info, context ){}}}
 
Capture exceptions in the error handling program of the entire job and perform compensation, for example:
 
We use the targetactivityname attribute of the compensateactivity activity to specify compensation for an activity.
The code for the entire workflow is as follows:
 Using System; Using System. componentmodel; Using System. componentmodel. design; Using System. collections; Using System. drawing; Using System. LINQ; Using System. workflow. componentmodel. compiler; Using System. workflow. componentmodel. serialization; Using System. workflow. componentmodel; Using System. workflow. componentmodel. design; Using System. workflow. runtime; Using System. workflow. Activities;Using System. workflow. Activities. Rules; Namespace Carycompensationdemo { Public sealed partial class  Carytourworkflow : Sequentialworkflowactivity { Public  Booktransaction exception Discontinuedproductexception1 = New  Booktransaction exception (); Public Carytourworkflow () {initializecomponent ();} Private void Tourstart_executecode ( Object Sender, Eventargs E ){ Console . Writeline ( "Preparing for a tour" );} Private void Bookticket_executecode ( Object Sender, Eventargs E ){ Console . Writeline ( "Reserve a train ticket" );} Private void Cancelticket_executecode ( Object Sender, Eventargs E ){ Console . Writeline ( "Annealing ticket" );} Private void Bookhotelok_executecode ( Object Sender, Eventargs E ){ Console . Writeline ( "Hotel Reservation successful" );} Private void Bookok_condition ( Object Sender, Conditionaleventargs E) {e. Result = False ;} Private void Bookexception_executecode ( Object Sender, Eventargs E ){ Console . Writeline ( "No hotel booked" );}}}




3. To use compensation, we need to load the persistence service in the Host Program. The following is the code of the Host Program:
 Using System; Using System. Collections. Generic; Using System. LINQ;Using System. text; Using System. Threading; Using System. workflow. runtime; Using System. workflow. runtime. Hosting; Namespace Carycompensationdemo { Class  Program { Static  Autoresetevent Waithandle = New  Autoresetevent ( False );Static void Main (){ Using ( Workflowruntime Workflowruntime = New  Workflowruntime ()){ Try { Const string Connectstring = "Initial catalog = workflowpersistence;
Data Source = localhost; Integrated Security = sspi ;" ; Workflowruntime. addservice ( New Sqlworkflowpersistenceservice (Connectstring); workflowruntime. workflowcompleted + = onworkflowcompleted; workflowruntime. workflowterminated + = onworkflowterminated; workflowruntime. workflowaborted + = worker; workflowruntime. startruntime (); Type Type = Typeof (Carycompensationdemo. Carytourworkflow ); Workflowruntime. createworkflow (type). Start (); waithandle. waitone ();} Catch ( Exception Ex ){ If (EX. innerexception! =Null ) Console . Writeline (ex. innerexception. Message ); Else Console . Writeline (ex. Message );} Finally {Workflowruntime. stopruntime ();}}} Static void Onworkflowaborted ( Object Sender, Workfloweventargs E ){ Console . Writeline ("Check whether the database connection is abnormal" ); Waithandle. Set ();} Static void Onworkflowcompleted ( Object Sender, Workflowcompletedeventargs E ){ Console . Writeline ( "Complete Workflow" ); Waithandle. Set ();} Static void Onworkflowterminated ( Object Sender, Workflowterminatedeventargs E ){ Console . Writeline (E. Exception. Message); waithandle. Set ();}}}
 
 
 
4. Finally, let's look at the running results:
 
 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.