《WF编程》系列之31 – 基本活动:事务(Transactions)与补偿(Compensation)

4.4 事务(Transactions)与补偿(Compensation)

在WF中,事务也遵从ACID(Atomic,原子性;Consistent,一致性;Isolated,不相关性;Durable,持久性)理论.也就是说,WF Runtime也会用到System.Transactions.Transaction类.Transaction类可以管理使用各种类型持久化存储的事务,例如Miscrosoft SQL Server和其它关系数据库.必要时,Transaction类还可以使用Microsoft Distributed Transaction Coordinator(MSDTC,微软分布式事务协调器)来协调两个相同重量级的事务.

4.4.1 TransactionSopeActivity

和System.Transactions.TransactionScope类相似,TransactionScope活动会启动一个事务并隐式的记录所有包含在事务里的活动.其TransactionOptions属性用来控制超时和事务的不相关级别.

如果没有错误发生,TransactionScope活动结束后会自动提交事务.如果在活动内部发生了异常,而且该异常并没有被Fault Handler处理,活动就会中断事务并回滚所有工作.

另外,TransactionScope活动中不可以包含TransactionScope活动作为其子活动.

4.4.2 补偿(Compensation)

就算工作流需要长时间运行,我们也不愿让一个事务花费数小时,数日甚至数周去执行.因为事务在提交之前会加锁记录以防止来自其它执行过程的查询.但是长期加锁事务不仅磨灭程序的可伸缩性,甚至会造成死锁.

所谓补偿,就是指抛开锁机制去尽可能快的提交事务并继续执行.如果之后某一点发生了错误,我们再去弥补之前完成的事务.也许这样做并不能逆转事务,但我们可以采取其它的措施(譬如取消)来弥补这个事务的失败所造成的影响.

在WF中,我们只能补偿实现了ICompensatableActivity接口的活动.在基本活动库中,CompensatableSequenceActivity和CompensatableTransactionScopeActivity都实现了这个接口.

4.4.3 CompensatableSequenceActivity

CompensatableSequence活动的功能相当于附加了补偿处理程序(Compensation Handler)的Sequence活动.我们可以通过右键菜单的View Compensation Handler来查看补偿处理器视图.

在补偿处理程序视图中,我们可以添加活动来对其子活动进行补偿.

4.4.4 CompensatableTransactionScopeActivity

CompensatableTransactionScope活动的功能相当于附加了补偿处理程序的TransacionScope,所以CompensatableTransactionScope活动也不能包含CompensatableTransactionScope活动作为其子活动.

在CompensatableTransactionScope活动的补偿处理程序视图中,我们可以使用活动来定义补偿的逻辑.

记住,补偿只当被补偿活动顺利完成时才会生效.

4.4.5 CompensateActivity

Compensate活动用来补偿之前完成的并且需要补偿的活动.我们只能补偿实现了ICompensatableActivity接口的活动.除了刚才提到的这两个基本活动库中的活动之外,我们还可以创建实现ICompensatableActivity接口的自定义活动.

为Compensate活动的TargetActivityName属性指定需要补偿的活动,Runtime就会执行目标活动的补偿处理程序.Compensate活动只能存在于错误处理程序或补偿处理程序中.当此活动在补偿处理程序中时,它还可以引发其子活动事务的补偿.  

或许这里让人有些难以理解,我再解释一下:

  • 可以把Compensate活动视作一个触发器,它可以触发目标活动的补偿处理程序,使其进行补偿.
  • 使用Compensate进行补偿的目标活动必须实现ICompensatableActivity接口,而且一定要顺利完成,因为我们之前提到,所谓补 偿就是一个”亡羊补牢”的过程,错误的产生和发现应该是在事务提交之后,此时Compensate活动需要置于错误处理程序中.
  • 如果某个可补偿的活动内部还包含了可补偿的子活动(比如嵌套的CompensatableSequence活动),而且其子活动在提交事务之后的某一步发 生了错误,那么在这个活动(而不是它的子活动)的补偿处理程序中添加Compensate活动可以对此错误进行补偿.

10 Comments

  1. 请���下博主,以下这句话怎么理解:

    CompensatableTransactionScope活动的功能相当于附加了补偿处理程序的TransacionScope,所以CompensatableTransactionScope活动也不能包含CompensatableTransactionScope活动作为其子活动.

  2. @赤脚小子
    首先,TransactionScope活动不可以作为TransactionScope活动的子活动;
    其次,CompensatableTransactionScope=TransactionScope+Compensation Handler;
    所以CompensatableTransactionScope也不可以作为CompensatableTransactionScope活动的子活动.

  3. 小乞丐熊

    好文章,請問一下,在TransactionScope活動中的子活動內拋出一個異常,為何該活動及流程都會觸發HandleFault事件呢?然後工作流就��束了。我想要的是,如果出錯了,就讓它回滾到這一活動之前的狀態,不要往下執行~比如說,我在TransactionScope活動中有一個HandleExternal活動,等待外部事件觸發後在它的Invoked方法中發生異常,我希望流程回滾到繼續等待外部事件這一步,請問大俠這樣可以做到不?頭痛幾天,WF基礎不太好,基本上是邊做項目邊學WF~

  4. 小乞丐熊

    謝謝大俠,可是我現在連回到整個活動之前 也做不到,直接拋出錯誤,然後就結束工作流了~?請問我該怎麼做呢?另有一問題:在動態增加子活動時,我是在工作流的Initialize方法中寫的代碼,給子活動中的一個SequenceActivity中加子活動,總是提示“無法新增或移除非可編輯活動上的子活動��”盼大俠不恥下問吶

发表评论

电子邮件地址不会被公开。 必填项已用*标注