业务流程: 学习 BPEL4WS,第 6 部分相关性、故障处理和补偿

来源:百度文库 编辑:神马文学网 时间:2024/03/28 19:27:28
使用 BPEL4WS 的业务流程: 学习 BPEL4WS,第 6 部分
相关性、故障处理和补偿

文档选项

将此页作为电子邮件发送

最新推荐

Java 应用开发源动力 - 下载免费软件,快速启动开发
级别: 初级
Rania Khalaf, 软件工程师, IBM TJ Watson Research Center
William A. Nagy, 软件工程师, IBM TJ Watson Research Center
2003 年 4 月 01 日
前几篇文章讲述了 BPEL4WS 的基础知识,您从中理解了所定义的各种活动以及将它们组合在一起的方式。在这篇文章中,我们来讨论 BPEL4WS 的一些高级属性,它们对于定义和执行业务流程至关重要。
既然您已经学习了 BPEL4WS 的一些基本概念,那现在我们就来深入学习它的一些更高级的主题。本文将向您概略讲述消息相关性、故障处理和补偿在 BPEL4WS 环境中的应用。




回页首
消息相关性是允许流程参与有状态会话的 BPEL4WS 机制。消息相关性有多种用途,例如,可以用它将回头客或已知客户匹配到长期运行的业务流程。当针对某一项用 BPEL 实现的 Web 服务的的消息抵达时,必须将该消息传送到适当的地方 - 不是传送到流程的新实例,就是传送到现有实例。消息相关性所要解决的问题是确定一条消息属于哪个对话,在 BPEL 中,此项任务即是指定位/实例化一个实例。
在许多分布式对象系统中,路由一条消息要涉及的一个方面就是检查消息的显式 instance ID,后者标识目的地。尽管路由过程很相似,但 BPEL 实例不是由一个显式的实例字段标识,而是由所交换的消息中的一个或多个关键字数据字段集合来标识。例如,在订单处理系统中,可以用订单号来标识流程的一个特定实例。在 BPEL 术语中,这些用于标识流程实例的数据字段的集合被称为相关集。
每个 BPEL 相关集都有一个与之相关联的名称,该名称由一些用 WSDL 定义的属性组成。 属性在 WSDL 文档中定义,是具有名称的类型化数据元素,它的值通过应用一个特定于消息的 XPath 表达式从 WSDL 消息的实例中提取而得。在 WSDL 中,用 propertyAlias定义每一个这样的映射。由于这些映射是特定于消息的,因此单个 属性可以有多个与之相关联的 propertyAlias。例如,一个 WSDL 文档可能陈述属性 name同时对应于 WSDL 消息 loginmsg中的 username部件和 WSDL 消息 ordermsg中的 lastname部件。通过同时使用属性和 propertyAlias,BPEL 创作者们就可以以一致的方式来引用信息中的单个逻辑片段,即使这一片段在一组消息中可能以不同的形式出现。
要使用相关集,BPEL 创作者可以通过枚举组成该集合的各属性来定义相关集,然后从 receive、 reply、 invoke或 pick活动引用该集合。BPEL 运行时使用这些定义和引用来确定它所感兴趣的信息片段,并在执行流程的不同阶段检查这些片段。流程的每个实例都会实例化为流程定义的每一个相关集。每个实例化(的过程)在流程实例的执行过程中恰好被初始化一次,随后仅在涉及到比较传入和传出消息时被使用。如果试图重新初始化一个相关集,或者使用一个未被初始化的相关集,那么运行时将会抛出一个 bpws:correlationViolation。提取由活动引用的相关集的值,无论是为了初始化还是为了比较,都会涉及到为组成该被引用的相关集的每个属性应用 processAlias(这个 processAlias 与正被检查的特定 WSDL 消息相对应)。
因为 receive和 pick活动提供进入流程的入口点,所以相关集常常会出现在这些活动中,以支持消息到实例的路由。如果一个相关集出现在 receive或 pick活动中,并且没有将 initiation属性设置为“yes”,那么当调用那个特定的 receive或 pick活动的消息抵达时,该活动就从传入的消息中提取组成该相关集的各属性的值,并将所提取的值与存储在那个流程的所有实例中的用于同一个相关集的值进行比较,然后将这个消息路由到有匹配值的实例中。类似地, reply和 invoke活动(这两种活动用于处理出站操作)中的相关集常常被用来验证传出消息中包含的数据和指定相关集实例中包含的数据是一致的。例如,如果一个相关集出现在 reply活动中,并且没有将 initiation属性设置为“yes”,那么该活动就从传出消息中提取组成该相关集的各属性的值,并将这些值与所存储的针对该实例的已实例化的相关集的值进行比较。如果发现对应于相关集的消息中的值和那些包含在实例的相关集中的值不同,那么运行时就会抛出一个 bpws:correlationViolation。在可以出现相关集的所有活动中, initiation属性用来告诉运行时应该使用输入到当前活动的消息中所包含的值来初始化相关集。在 invoke活动中出现的相关集还有另一个属性 pattern,它指定在 invoke活动执行过程中所要应用的相关集。 pattern属性可以取值“in”,表示要在针对调用的响应返回的时候应用这个相关集,也可以取值“out”,表示在开始进行调用的时候就应用这个相关集,或者取值“both”,这自然表示在两个阶段都要应用这个相关集。
在单个活动中可以出现多个相关集,其中一些被初始化,一些用来作比较。目前的 BPEL 规范没有定义根据多个相关集定位一个实例的语义。




回页首
在执行一个 BPEL 流程时,无论是在被调用的服务中还是流程本身都可能发生错误。BPEL 提供了一种机制,这种机制可以显式地捕获这些错误并通过执行在 fault handler元素中指定的子程序来处理这些错误。此外,已完成的活动在晚些时候可能需要被撤销,因为这些活动是一个时间更长的事务的一部分,而这个事务不得不被终止。 补偿处理程序允许流程的创建者定义用于撤销一个工作单元并把数据恢复到执行该工作之前的样子的特定操作。
处理这些情况通常会影响到相互关联的一组活动。在 BPEL 中,通过将这些活动封装 作用域(scope)结构化活动来实现这个处理。 作用域为嵌套在其中的活动提供上下文,并且也是定义故障处理程序和补偿处理程序的地方。因此,您可以将作用域看作是一个可补偿的、可恢复的工作单元的封装。
整个流程提供全局作用域:它包含一个主活动并允许指定故障处理程序和补偿处理程序。它还可以定义数据容器和相关集。然而,BPEL 的未来方向指明所有作用域都将具有上述功能,并且在一个作用域中定义的容器将只能为嵌套在该作用域中的活动所见。
为了理解作用域如何捕获或传播在它内部首先发生的错误,我们首先回顾一下 BPEL 活动的生命周期。在一个活动的父代和传入链接将它激活之前,一个活动始终保持休止。一旦这个活动从它的父代处获得控制权,并且其所有传入链接都已抵达,它就会评估它的连接条件,此时会发生以下两种情况之一:要么因为不满足连接条件而抛出一个 joinFailure故障,要么就正常运行。假设为后者,活动在成功地运行之后,将评估并激活它的所有传出链接,然后结束。
另一方面,活动可能因自身是一个返回故障(这个故障是活动在执行时会发生的 BPEL 内建故障之一)的调用或者是一个 throw活动而在运行时发生故障。在这种情况下,该活动会通知它所属于的作用域。作用域在收到故障后,它就必须停止所有嵌套在它内部的活动。另一个可能导致活动无法成功运行的原因是一个活动永远无法从它的父代获得它全部的链接或控制权。例如,对于与发生故障的活动同在一个作用域但要在该活动完成之后再运行的活动,就可能会无法成功运行,对于分支(switch)语句中永远不会被运行的分支活动,也可能会无法成功运行。对于这两种情况,活动都无法成功运行并完成,此时活动需要用一个否定值将它的所有传出链接发送出去。
BPEL 能够在活动嵌套的不同级别捕获并处理错误。可以在任何作用域中定义故障处理程序,故障处理程序可以绑定到特定类型的故障(由故障的限定名或消息类型定义),或者绑定到未被针对性更强的处理程序捕获到的任何故障。处理程序仅包含一个将在错误发生的时候运行的活动。例如,处理程序可能包含一个 reply 活动,用来通知伙伴发生了一个错误。
前面已经提到,作用域一旦接收到一个故障所做的第一件事就是停止嵌套在它内部的所有活动。在缺省情况下,作用域会停止它的活动,然后将故障重新抛给它的父代,如此反复直至将这个故障抛至最顶层的流程。当一个作用域重新抛出故障时,作用域本身接着就会异常终止,并以一个否定值将它所有的传出链接发送出去。然而,处理程序允许任何作用域拦截一个故障并采取适当的操作。一旦故障在作用域中被处理,作用域会照常评估它的传出链接的值并正常结束。这种情况如下图 1所示。

在这幅图中,由于活动的传入链接的值中有一个为否定值且连接条件是链接值的布尔 与值,因而导致活动发生故障。该活动因此将这个故障抛给它的作用域,且您可以看见从这个活动传出的链接变为否定。由于作用域本身没有针对接收到的故障的处理程序,因此它重新抛出这一故障。它的上一层作用域是流程本身。您看见内层作用域的链接变为否定值,因为作用域无法处理问题本身并且因此异常终止。而流程却因为拥有一个处理程序(可以处理接收到的故障),因而得以正常完成。由此可以得知,如果处理程序在内部作用域中的话,那么由它传出的链接就会被照常评估,故障也就不会被抛给流程了。
invoke 活动具有一种用来直接按照活动定义对处理程序进行定义的快捷机制。当这个行为被包装在一个将带有这些指定的处理程序的作用域中时,它的效率会很高。
BPEL 定义有一组用来通知错误的内建故障,这些错误的例子如赋值类型不匹配、作用域强制终止一个它嵌套的作用域以及激活一个不包含匹配的 receive 活动的 reply 活动。BPEL 引擎负责检测这些故障并将它们抛给适当的作用域。
在运行一个业务流程的过程中,可能需要撤销那些已经成功完成的步骤中的某一步。这些撤销步骤的指定是通过使用补偿处理程序来定义的,补偿处理程序可以在作用域级别上进行定义。每一个处理程序包含一个在作用域需要被补偿时运行的活动。
在这样一个处理程序中的活动必须看到容器数据与作用域完成时是一样的。由于各活动共享容器和由 while活动引起的循环,所以,支持补偿功能的正在完成中的作用域为数据保存一个快照,以备处理程序将来可能要用到。
一旦作用域成功地完成,它的补偿处理程序就已准备好可以运行。这可以在以下两种的任意一种情况中均可发生:显式补偿或隐式补偿。显式补偿在执行 compensate活动时发生。这个活动可以在作用域的故障或补偿处理程序中发生,这个作用域直接封装了要被补偿的作用域。以这种方式回滚的作用域必须被命名,因为 compensate活动就是通过这个名称标识它们的。当一个 compensate活动被触及时,它在指定的作用域内运行补偿处理程序。
另一方面,隐式补偿在故障被处理并传播时发生。请考虑这样的情景,作用域 A包含一个已经正常完成的可补偿的作用域 B,但随后另一个嵌套在 A中的活动抛出一个故障。隐式补偿通过运行它的补偿处理程序来确保撤销在作用域 B中所发生的一切。因此,一个作用域的隐式补偿遍历它所嵌套的全部作用域,并按那些作用域的 完成次序的逆序运行它们的补偿处理程序。




回页首
我们在本文中讲述了相关性和故障处理(包括补偿)的高级概念。下一篇文章将为您提供一个可运行的示例,这个示例将阐明如何使用相关性将消息匹配到适当的实例,以及如何使用故障处理程序来捕获并处理流程中的错误。




回页首
请参加关于本文的讨论论坛。(您也可以点击文章顶部或底部的 讨论来访问此论坛。)
从alphaWorks下载Business Processes for Web Services Java Runtime。
请阅读 使用 BPEL4WS 的业务流程专栏以前的文章。
 




回页首


Rania Khalaf 是 IBM T.J. Watson Research Center 的 Component Systems 小组的一名软件工程师。2001 年,她从 MIT 获得学士学位和工程硕士学位后加入 IBM。Rania 是 IBM BPEL4WS 引擎 BPWS4J 的创作者之一,您可以从 alphaWorks 获得 BPWS4J。您可以通过rkhalaf@watson.ibm.com与 Rania 联系。

 

William A. Nagy 是 IBM T.J. Watson Research Center 的 Component Systems 小组的一名软件工程师。他是 WS-Inspection 的创作者之一,也是 BPWS4J、Apache SOAP、WSTK 和 WSGW 的开发者之一。他拥有哥伦比亚大学(Columbia University)计算机科学专业的硕士学位。您可以通过nagy@watson.ibm.com与 William 联系。
_xyz