一:事务是你在做一组更新时要不成功,要不失败,不可能只部分更新。事务最经典的使用场合就是在关系型数据库中。补偿是取消之前已经成功的操作,在我们的工作流中我们可能完成一项任务有很多活动组成,比如我们的活动都使用了TransactionScopeActivity,我们在之后发现错误了,想要取消之前成功的操作,这个和事务就没有关系了,因为事务已经成功了。这个时候我们就可以使用补偿。你可以逻辑上划分一组活动,指定一个补偿处理器给这组活动。在补偿处理器中你声明如果补偿成功了就执行该组活动。补偿处理器就会自动跟踪异常了。或者我们直接使用CompensateActivity。
事务能自动做回滚操作,而补偿却不能,补偿只是提供了一个地方给你做取消的工作,但具体的代码就要你自己实现了。WF实现了ICompensatableActivity接口的可以有补偿的功能。WF自己提供了两个CompensatableTransactionScopeActivity
,CompensatableSequenceActivity。前一个活动支持事务和补偿。CompensatableHandlerActivity是你执行补偿的容器。你也可以明确的使用CompensateActivity,该活动允许你使用其TargetActivityName来指定对某个活动使用补偿。不过该活动只能被加到CompensationHandleActivity,FaultHandlerActivity,CancellationHandlerActivity中。
二:下面以一个具体的例子来说明补偿是如果使用的,假如你计划要去旅游,那么你在出发前会先定火车票,然后在定酒店。那么如果你定到火车票了,可是当你去定酒店的时候你发现所有的酒店都已经被别人预定了,这个时候你定的火车票也没有用了,只好退订了。在我们的程序中我们用补偿来完成这个功能。下图是我们设计的工作流:
我们的流程是这样的,首先预定火车票,然后在预定酒店,在预定酒店的时候我们会判断是否成功。如果不成功我们会抛出一个异常。在预定火车票活动(BookTicket)放到了CompensatableTransactionScopeActivity活动中,其中的补偿处理我们执行退订火车票的程序,如下图:
在预定酒店的时候,如果预定不成功我们会使用上图中的BookFail(ThrowActivity)活动来抛出一个异常,下面是我们自定义的一个异常类,代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.Serialization; namespace CaryCompensationDemo { [SerializableAttribute()] public class BookHotelException : Exception { public BookHotelException() : base() { } public BookHotelException(string message) : base(message) { } public BookHotelException(string message, Exception innerException)
: base(message, innerException) { } protected BookHotelException(SerializationInfo info, StreamingContext context)
: base(info, context) { } } }
在整个工作的错误处理程序中来捕获异常,并执行补偿处理,如下图:
我们使用CompensateActivity活动的TargetActivityName属性来指定对某个活动使用补偿。
整个工作流的代码如下:
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 BookHotelException discontinuedProductException1 = new BookHotelException(); public CaryTourWorkflow() { InitializeComponent(); } private void TourStart_ExecuteCode(object sender, EventArgs e) { Console.WriteLine("准备去旅游咯"); } private void BookTicket_ExecuteCode(object sender, EventArgs e) { Console.WriteLine("预定火车票"); } private void CancelTicket_ExecuteCode(object sender, EventArgs e) { Console.WriteLine("退火车票"); } private void BookHotelOK_ExecuteCode(object sender, EventArgs e) { Console.WriteLine("酒店预定成功"); } private void BookOk_Condition(object sender, ConditionalEventArgs e) { e.Result = false; } private void BookHotelException_ExecuteCode(object sender, EventArgs e) { Console.WriteLine("没定到酒店"); } } }
三:使用补偿我们需要在宿主程序中加载持久化服务,下面是宿主程序的代码:
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 += OnWorkflowAborted; 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("请检查数据库连接是否异常"); waitHandle.Set(); } static void OnWorkflowCompleted(object sender, WorkflowCompletedEventArgs e) { Console.WriteLine("完成工作流"); waitHandle.Set(); } static void OnWorkflowTerminated(object sender, WorkflowTerminatedEventArgs e) { Console.WriteLine(e.Exception.Message); waitHandle.Set(); } } }
四:最后我们看下运行结果吧:
发表评论
-
平淡的2007
2007-12-24 08:04 817早上起来,送女朋友去公交车站,然后回来赶紧打开电脑,先 ... -
DreamSpark发布,高校学生免费使用Visual Studio 2008 Professional Edition 等微软软件
2008-02-20 13:23 1415今天上网无意中搜索到学生可以免费使用VS2008专业版,后来又 ... -
坚持学习WF(1):从HelloWorld开始
2008-04-04 16:30 892[置顶]坚持学习WF文章索 ... -
坚持学习WF(2):WF创作模式和设计时工具
2008-04-05 17:19 639[置顶]坚持学习WF文章索 ... -
坚持学习WF(3):WF框架概览
2008-04-08 07:27 783[置顶]坚持学习WF文章索 ... -
坚持学习WF(4):活动(Activity)和依赖属性(DependencyProperty)
2008-04-12 00:01 1148[置顶]坚持学习WF文章索引 活动(Activity) 活动 ... -
坚持学习WF(5):自定义活动(CustomActivity)
2008-04-13 15:25 929当WF提供的标准活动不能满足我们的需求的时候,我们就需要定义自 ... -
MOSS点滴(1):如何开发和部署feature
2008-04-16 21:35 835Features 是MOSS 2007以开箱即用的一套新功能, ... -
MOSS点滴(2):自定义Application Page
2008-04-19 20:07 844在MOSS中后台管理的页面都是Application Pag ... -
坚持学习WF(6):开发可复用的宿主程序
2008-04-21 21:45 695我们之前写工作流宿主 ... -
MOSS点滴(3):说说MOSS中的母版页
2008-04-25 21:15 1187MOSS中有两种页面:Site P ... -
MOSS点滴(4):实现Form认证
2008-04-29 21:12 705本文主要参考了网上的一些文章,但有些文章有些地方说的不是很明确 ... -
坚持学习WF(7):流程控制(Flow Control)
2008-04-30 18:10 839本文主要说说WF中和流 ... -
坚持学习WF(8):本地服务之调用外部方法
2008-05-09 08:17 761WF提供了一组核心服务 ... -
MOSS中的WebPart开发
2008-05-10 13:53 1060由于在asp.net1.1的时候asp.net中还没有webp ... -
坚持学习WF(9):本地服务之事件处理
2008-05-28 07:49 800[置顶]坚持学习WF文章索引 一:先来介绍两个活动 Even ... -
坚持学习WF(10):在工作流中使用关联
2008-06-01 13:03 692[置顶]坚持学习WF文章索 ... -
坚持学习WF(11):工作流通信与队列
2008-06-07 15:45 735[置顶]坚持学习WF文章索引 WF 提供的通信模型是构建于 ... -
MOSS中创建自定义内容类型
2008-06-12 20:23 1106一:简要介绍 某类内容 ... -
.NET中IDisposable接口的基本使用
2008-06-15 12:01 950首先来看MSDN中关于这个接口的说明: [ComVisible ...
相关推荐
坚持学习WF(17):WF中的补偿 事务是你在做一组更新时要不成功,要不失败,不可能只部分更新。事务最经典的使用场合就是在关系型数据库中。补偿是取消之前已经成功的操作,在我们的工作流中我们可能完成一项任务有很...
坚持学习WF(2):WF创作模式和设计时工具 坚持学习WF(3):WF框架概览 2.3两篇主要全面的阐述了WF框架和Visual Studio对开发WF的一些设计时的工具。 坚持学习WF(4):活动(Activity)和依赖属性(DependencyProperty) ...
坚持学习WF(17):WF中的补偿 事务是你在做一组更新时要不成功,要不失败,不可能只部分更新。事务最经典的使用场合就是在关系型数据库中。补偿是取消之前已经成功的操作,在我们的工作流中我们可能完成一项任务有很...
在本篇“坚持学习WF(1):从HelloWorld开始”的源码分析中,我们将深入理解WF的基础知识和创建第一个工作流的步骤。 首先,让我们了解WF的基本概念。WF提供了一种模型化业务流程的方式,通过活动(Activities)来表示...
总的来说,自定义活动是WF中实现业务逻辑灵活性的关键。通过深入理解和实践自定义活动的创建,开发者可以构建出符合业务需求的高效、可维护的工作流应用程序。通过对`CaryActivity`源码的学习和分析,我们可以更好地...
- **第17章:补偿、确认和取消**:深入探讨如何处理工作流的异常情况,包括补偿操作、确认和取消。 - **第18章:集合**:介绍如何在工作流中使用集合来管理数据。 - **第19章:与Workflow 3.5的互操作性**:讲解...
3. **WF活动**:WF的核心是活动,它们是工作流中的最小执行单元。活动可以是内置的,如If条件判断、Assign赋值,也可以是自定义的,满足特定业务需求。活动可以通过组合和嵌套形成复杂的工作流逻辑。 4. **WF生命...
接着,"坚持学习WF(2):WF创作模式和设计时工具"会深入到WF的设计环境,比如Visual Studio中的工作流设计器,讲解如何利用这些工具来创建和编辑工作流。此外,还会介绍几种常见的工作流模式,如顺序工作流、并行工作...
《爱普生WF-7720、WF-7710、WF-7210维修手册:含报错代码解释》 本手册详细介绍了爱普生WF-7720系列、WF-7710系列以及WF-7210系列彩色喷墨打印机的拆机分解、故障代码解析及解决思路。这些打印机支持云打印功能,是...
- **活动(Activity)**:WF中的基本执行单元,代表了工作流的一部分逻辑。 - **工作流引擎**:负责解释活动并执行工作流的组件。 - **持久化**:WF支持将工作流的状态保存到持久存储中,以便在后续时刻恢复执行。 ##...
活动是WF中最基本的构建块,它们代表了流程中的一个操作或步骤。你可以使用内置的活动,如If、Parallel、SequentialWorkflowActivity等,也可以自定义活动以满足特定需求。在设计工作流时,你会用到这些活动,通过...
《在.NET 4.0中开始使用WF Windows工作流》一书由Mark J. Collins撰写,深入探讨了在.NET框架4.0版本中如何利用Windows Workflow(WF)技术来构建和管理复杂的工作流程。该书作为一本入门指南,旨在帮助读者理解和...
活动是WF中最基本的构建块,它可以代表一个业务操作或者是一个更复杂的工作流子流程。工作流是由一系列活动组成的逻辑流程,它们共同定义了一个业务过程。运行时是WF执行工作流的地方,它负责管理工作流的生命周期,...
WF4 Cookbook中文版是针对Microsoft Windows Workflow Foundation 4.0(WF4)的一份技术指南,旨在帮助开发者...文档“wf4Cookbook翻译.docx”包含了详细的技术说明和示例代码,是学习和参考WF4工作流开发的重要资源。
在本文中,我们将深入探讨如何更换爱普生WF系列打印机的喷头,特别是针对WF-7620、WF-7610、WF-7110以及WF-3641型号的打印机。这些打印机是爱普生公司推出的高效商用喷墨打印机,以其高质量的打印效果和强大的功能而...
爱普生WF-7620、WF-7610和WF-7110是爱普生公司推出的高效办公喷墨打印一体机,它们都具备打印、扫描、复印和传真功能,适合中小型企业或家庭办公室使用。这些机型采用爱普生的DuraBrite Ultra颜料墨水,能提供高质量...
Beginning WF: Windows Workflow in .NET 4.0 By Mark Collins Publisher: Apress 2010 | 500 Pages | ISBN: 1430224851 | PDF | 4 MB Windows Workflow Foundation is a ground-breaking addition to the core ...