【深入浅出WF】——补偿(Compensation)
基本概念
首先我们来回顾下事务的加锁机制。事务在提交之前会加锁记录以防止来自其它执行过程的查询.但是长期加锁事务不仅磨灭程序的可伸缩性,甚至会造成死锁。
所谓补偿,简单的说就是时空隧道,对之前做过的正确的事情重新做一遍。它抛开锁机制去尽可能快的提交事务并继续执行.如果之后某一点发生了错误,我们再去弥补之前完成的事务,也许这样做并不能逆转事务,但我们可以采取其它的措施(譬如取消)来弥补这个事务失败所造成的影响。
在WF3.5中,我们只能补偿实现了ICompensatableActivity接口的活动.在基本活动库中,CompensatableSequenceActivity和CompensatableTransactionScopeActivity都实现了这个接口.。(待核实)
1.1 CompensatableSequenceActivity
CompensatableSequenc活动的功能相当于附加了补偿处理程序(Compensation Handler)的Sequence活动.我们可以通过右键菜单的View Compensation Handler来查看补偿处理器视图
在补偿处理程序视图中,我们可以添加活动来对其子活动进行补偿。
1.2 CompensatableTransactionScopeActivity
CompensatableTransactionScope活动的功能相当于附加了补偿处理程序的TransacionScope,所以CompensatableTransactionScope活动也不能包含CompensatableTransactionScope活动作为其子活动.
在CompensatableTransactionScope活动的补偿处理程序视图中,我们可以使用活动来定义补偿的逻辑.
记住,补偿只当被补偿活动顺利完成时才会生效.
1.3 CompensateActivity
我们只能补偿实现了ICompensatableActivity接口的活动.除了刚才提到的这两个基本活动库中的活动之外,我们还可以创建实现ICompensatableActivity接口的自定义活动.
为Compensate活动的TargetActivityName属性指定需要补偿的活动,Runtime就会执行目标活动的补偿处理程序.Compensate活动只能存在于错误处理程序或补偿处理程序中.当此活动在补偿处理程序中时,它还可以引发其子活动事务的补偿. 或许这里让人有些难以理解,我再解释一下:
可以把Compensate活动视作一个触发器,它可以触发目标活动的补偿处理程序,使其进行补偿.
使用Compensate进行补偿的目标活动必须实现ICompensatableActivity接口,而且一定要顺利完成,因为我们之前提到,所谓补偿就是一个”亡羊补牢”的过程,错误的产生和发现应该是在事务提交之后,此时Compensate活动需要置于错误处理程序中.
如果某个可补偿的活动内部还包含了可补偿的子活动(比如嵌套的CompensatableSequence活动),而且其子活动在提交事务之后的某一步发生了错误,那么在这个活动(而不是它的子活动)的补偿处理程序中添加Compensate活动可以对此错误进行补偿.
定义补偿
简述
Compensate活动用来补偿之前完成的并且需要补偿的活动。因此
CompenationHandler当工作流有异常或活动执行取消完成后方执行;
ConfirmationHandler为工作流正常执行完成后方执行;
CancellationHandler为活动取消时方执行。
Result:活动执行结果的参数。
代码方式实例:
new CompensableActivity
{
Body = new WriteLine { Text = " CompensableActivity: Do First Action" },
ConfirmationHandler = new WriteLine { Text = " CompensableActivity: Confirm First Action" },
CompensationHandler = new WriteLine { Text = " CompensableActivity: Compensate First Action" },
CancellationHandler = new WriteLine { Text = " CompensableActivity: Cancel First Action" },
Result = tokenA
},
声明方式实例:
因为使用xaml进行定义,xml属于声明式编程(Declarative program)的一种。
显示调用补偿活动
使用Confirm和Compensate来显示调用。
使用
官方实例
eg1简单的补偿活动
简介:在正常的执行顺序中,使用补偿活动给将要做的定义的工作。这个工作在晚点有必要去补偿这个动作。
相关知识点:
使用ManualResetEvent来创建一个线程供application来运行。
// Executing the sequence of two actions that complete with success
Console.WriteLine("Execution with success:");
application = new WorkflowApplication(BuildASequenceofCompensableActions());
ManualResetEvent resetEvent = new ManualResetEvent(false);
application.Completed = delegate(WorkflowApplicationCompletedEventArgs e)
{
resetEvent.Set();
};
application.Run();
resetEvent.WaitOne();
eg2取消引发的补偿活动
简介:使用补偿范围来分组一系列可补偿的活动集,使它们与其他补偿范围相隔离。
相关知识点
CompensationToken,用来通过记录发放令牌来安排补偿活动的执行顺序。
eg3 客制化补偿
简介:使用补偿和补偿处理器来定义客制化的补偿逻辑。
eg4 分布式补偿
简介:使用补偿实现工作流服务宿主并行运作。