代码改变世界

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

2007-09-28 15:34  Windie Chai  阅读(3559)  评论(9编辑  收藏  举报

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活动可以对此错误进行补偿.