Welcome

首页 / 软件开发 / .NET编程技术 / WF从入门到精通(第十五章):工作流和事务

WF从入门到精通(第十五章):工作流和事务2010-06-03 cnblogs GuoYong.Che学习完本章,你将掌握:

1.了解传统的事务模型以及这种模型在哪些地方适合去使用,哪些地方不适合使用

2.懂得在哪些地方不适合传统的事务以及什么时候是补偿事务的恰当时机

3.看看怎样回滚或补偿事务

4.看看怎样修改默认的补偿顺序

如果你是写软件的,你迟早需要去理解事务处理。事务处理(transactional processing)在这个意义上是指写那些把信息记录到一个持久化资源的软件,这些持久化资源如数据库、Microsoft消息队列(它在底层使用了一个数据库)、带事务文件系统的Windows Vista以及注册表存取或者甚至是其它一些支持事务处理的软件系统。持久化资源不管发生什么事情,一旦数据被记录下来就会保留这些写入的信息。

事务对于任何业务流程都是关键的,因为通过事务,你能确保你的应用程序中数据的一致性。假如业务流程维持一个错误但仍要持久化一些数据,那么这些错误的数据很有可能会波及到整个系统,这就留给你一个问题:哪些数据是正确的,哪些数据是错误的。试想从一个在线商家订购这本书,可是却发现商家和你的信用卡交易“出了点小意外”,收取了你书的标价的100倍而不是他们的折扣价。当像这样的错误可能发生时,事务处理就不再是一个可笑的或者避而不谈的话题。

理解事务

事务处理,其核心就是管理你的应用程序状态。对于状态,我实际指的是应用程序的所有数据的状况。当应用程序的所有数据是一致的,那么该应用程序就处于一个确定状态。假如你把一条新的客户记录添加到你的数据库中,则此过程需要两个插入(一是新增一条通常的包含有把地址和你的客户联系在一起的信息的行记录,另一条是记录真实地址信息),添加通常的行记录成功后,但添加它的地址时却失败了,这就使你的应用程序处于一个不确定状态。当某人试图检索该地址将发生什么呢?系统会提示到地址应该在此,但真实的地址记录已丢失。你的应用程序数据现在是不一致的。

为确保这两个操作成功,事务起到了作用。一个事务本身是一个单一的工作单元,它要么全部成功要么全部失败。这并不是说你不能更新两个不同的数据库表。它刚刚的意思是两个表的更新被看作是一个单一的工作单元,两个都必须被更新否则都失败。假如其中一个或者两个更新失败,理想情况下是你想让系统回到刚刚你试图更新这些表之前的状态。没有迹象表明试图更新这些表的操作是非成功的话,你的应用程序就应该继续前进,但更重要的是,你不想有来自更新不成功的一个表里有而另一个表里却没有的数据。

备注:有整卷书全部写和事务及事务处理相关知识的书籍。尽管我将描述的解释Microsoft Windows Workflow Foundation(WF)是怎么支持事务的相关概念足够深,但我不可能在本书中以相当深的深度覆盖事务处理的方方面面。假如你还没有重新看看.NET 2.0中通常的事务支持的话,你应该这样去做。WF的事务处理模式和.NET 2.0的事务支持非常紧密,你可以在下面的论文中找到有用的知识去理解WF的事务支持:msdn2.microsoft.com/en-us/library/ms973865.aspx。

传统上,事务来自于一个单一的模式:XA或两阶段提交(two-phase commit)类型的事务。但是,随着基于Internet通信的出现以及需要提交长时间运行的事务的要求,引进了新一些的称作补偿式事务的事务类型。WF支持这两种类型。我们将首先讨论传统的事务,然后我们将提到使用这种类型的事务是一个低级的架构选择,再后我们将讨论补偿式事务。

传统(XA)事务

已知的第一个实现了事务处理的系统是一个航空公司的预订系统。对于需要预订多个航班的请求,假如任何一个单独的航班不能预订,则该预订就不能进行。系统设计师知道这些并设计了一个我们今天称为X/Open分布式事务处理模型,简称XA的事务化方式来进行处理。(看看en.wikipedia.org/wiki/X/Open_XA。)

XA事务涉及到XA协议,即我先前提到的两阶段提交和三个实体:应用程序、资源和事务管理器。应用程序也就是指你的应用程序。资源是一个设计的用来加入到XA类型的事务中去的软件系统,也就是说它参与事务并懂得怎样参与两阶段提交数据以及提供持久性(很快将进行讨论)。事务管理器监视整个事务处理流程。

因此什么是两阶段提交呢?最后,想像你的应用程序需要写入数据,也就是说一个数据库。假如写入过程在事务下执行,数据库就保持这些要被写入的数据直到事务管理器发出一条准备(prepare)指令为止。在那时,数据库以一个表决(vote)作为响应。假如该表决是要前进并把数据提交(写入)到表中,那么事务管理器则进入并参与资源,假如有的话。

假如所有资源对提交数据都表决成功,则事务管理器发出一个提交(commit)指令然后每一个资源就把数据写到它内部的数据存储中。只有到那时指定要写入你的表中的数据才真正地插入到数据库中。

假如任何一个资源有问题并且没有对提交数据进行表决,则事务管理器发出一个回滚(rollback)指令。所有参与进事务的资源就必须销毁和事务相关的信息,没有东西被永久的记录保存下来。

一旦数据被提交,XA协议会保证事务结果的持久性。数据是一致的,并且应用程序也处在一个确定状态中。