长时间运行的处理过程和应用程序状态 记住,XA类型的事务的整个前提是假如事务回滚的话,你的应用程序将回到它的初始状态。但是考虑一下这个情况:假如事务花费了过长的时间才提交的话你的应用程序会发生什么呢? 在我回答之前,假想你的在线交易系统收到了一个客户的订单,但是信用卡验证的过程中被中断了。无疑你的处理过程在一个事务中进行,因为假如某些地方失败的话你就不想再去收取该客户的款项。但是与此同时,其它客户又正在发来订单,假如你运气不错的话,这是大量的订单。假如第一个客户的交易失败后,订单在此期间发来将发生什么呢? 假如系统的目的不是为了隔离单独的一个订单处理失败,那么正确的做法是把系统完全回滚到它的原始状态。但是考虑这种情况则意味着,我们不仅会丢失第一个客户的订单,也会丢失在此期间其它每一个客户发来的订单。即使这可能只有两个订单,但也不是很好。假如这是10,000份订单呢...损失的收入数额是不能容忍的。 当然,我们将保留这10,000份订单并把刚刚处理的第一份订单放到一个孤立的事件中,但是在这种情况下我们同时也有可能会有意破坏事务属性中的某一个来保留这些订单收入。这是一个风险,需要进行估量,但通常在现实世界情况下我们必须接受这一风险。 被破坏的属性其实是原子性,出于这个原因,写事务处理系统的人会努力在尽可能短的时间内持有事务。你做的仅仅只能是你事务范围内所必须要做的事,你要尽可能高效地做这些事以便事务快速地完成。 现在我们进入另外一种复杂情况:Internet。你的客户正在线发送订单,网络速度是出了名的慢甚至中断。因此,在Internet之上的事务处理是有疑虑的。 补偿作为一个解决办法 这正是创建所需要的补偿事务的情况。假如我给你五个苹果,过程使用XA-类型的事务,事务失败时,时间会回滚到我开始给你苹果的那一刻。在某种意义上说,历史会被重写以致这五个苹果没有被首先考虑到。但是假如我是在一个补偿式事务中给你的五个苹果的话,事务失败进行补偿(以便我们维护一个确定的应用程序状态)时,你必须返回五个苹果给我。看起来差别很小,但两种类型的事务之间存在明显的区别。 当写XA类型的事务时,负责回滚失败事务的职责落在资源上,例如你的数据库。相反,当一个补偿式事务失败时,作为事务参与者,你有责任通过提供一个事务补偿功能来为你的事务部分提供补偿。假如你扣除了某个在线客户信用卡中的金额并在后来被告知要补偿,你会立即向该客户账户存入你起初扣除的相同数目的金额。在一个XA类型的事务中,该账户绝不会在一开始就被扣除。对于补偿式事务来说,你发起两个操作:一个是扣除账户,另一个是后来存入它。 备注:毫无疑问,它将是一个极好的系统,它能在Internet上成功执行XA类型的事务。但是要非常仔细地构思你的补偿功能,注意各个细节。如果你不这样做的话,你可能由于一错再错而使情况更加糟糕。写出准确的补偿功能通常并不容易。 向你的工作流中引入事务 总的来说,在WF中引入事务和拖拽一个基于事务的活动到你的工作流中一样简单。但是,如果你正使用事务活动话,你应该知道更多一些的东西。 工作流运行时和事务服务 当你在你的工作流中使用基于事务的活动时,需要两个可插拔的工作流服务。首先,因为基于事务的WF活动需要标注PersistOnClose特性(在第6章“加载和卸载实例”中提过),因此你也必须启动SqlWorkflowPersistenceService。假如你没有的话,WF不会崩溃,但是你的事务也不会提交。 或许在本章更感兴趣的是DefaultWorkflowTransactionService。 这个服务为你事务操作的启动和提交负责。没有这样一个服务的话,工作流运行时内的事务是不可能实现的。 备注:你可以创建你自己的事务服务,尽管这超出了本章的范围。所有WF事务服务都派生自WorkflowTransactionService,因此创建你自己的服务基本上就是重写(override)你想改变的基类功能。实际上,WF用了一个自定义的事务服务:SharedConnectionWorkflowTransactionService来承载共用的Microsoft SQL Server连接。在msdn2.microsoft.com/en-us/library/ms734716.aspx可找到更详细的信息。 失败处理 对于事务失败,尽管在你的工作流中并不需要你去处理失败过程,但这是个好习惯。我不想提它的原因是它被认为是一个最佳做法。我提到它的原因是你可能去实现你自己的,在真正失败之前能自动检查异常并重新尝试事务处理的事务服务。尽管对这些要怎么做进行演示超出了本章的范围,但你应该知道这是可以做到的。 环境事务(ambient transaction) 基于事务的活动都在被称为环境事务的东西下工作。当你的工作流进入一个事务范围内的时候,工作流事务服务会自动为你创建一个事务。这不需要去尝试并建立你自己的事务。所有嵌入到事务范围中的活动都属于这一个环境事务,假如事务成功它们就都提交,否则就回滚(或者补偿)。 本文来源:https://www.wddqw.com/doc/e004a28d360cba1aa811dacb.html