BPEL

面向 WLI 用户的 SOA 套件概要

处理事务

作者:Kathryn Holden、Antony Reynolds 和 Tejas Joshi

2008 年 9 月发布

面向 WLI 用户的 SOA 套件概要系列的第一部分将介绍与 WebLogic Integration 的事务处理功能对应的 Oracle BPEL 流程管理器功能。

下载:
 Oracle SOA Suite

引言

设计应用程序时,事务始终是一切的中心。回到开发人员可以通过代码控制事务的时候,事务易于定义和管理。选择余地可能不大,但开发人员知道哪些是可以预期的。

过去十年间,Java 2 企业版 (J2EE) 和其他技术的出现鼓励开发人员将事务留给容器处理。但对于不甚了解基于容器的服务的开发人员,这是个障碍。

在容器中自动创建了事务划分语句之后,一切变得更糟,开发人员对所发生的一切知之甚少。

本文希望揭开 WebLogic Integration (WLI) 和 Oracle BPEL 流程管理器 (BPEL PM) 中容器管理的和容器定义的事务的神秘面纱。

一个有关 Oracle BPEL 流程管理器的常见误解是,它不支持全局 XA 事务组。造成这种误解的原因可能是 BPEL PM 与 WLI 不同,它不包括任何专门标记为“启动事务”或“停止事务”的活动。而是基于所涉及活动的类型对事务组进行隐式描述。

我们先从一个非常简单的 WLI 事务示例入手,了解如何在 BPEL PM 中实施它。之后,我们将探讨更高级的话题,如补偿事务。

简单事务流程

在本示例中,一个流程将更新三个数据库并将一条 JMS 消息放入队列中。所有资源都支持 XA,这个流程形成了一个全局事务。

在 WLI 中实施流程

与 BPEL PM 类似,WLI 中的业务流程本质上也是事务型的。流程的每个步骤都在 JTA 事务环境中执行。事务可以确保一个或多个操作作为工作的一个原子单元执行。如果事务中的一个操作失败,所有操作都将回滚,应用程序将返回到先前的状态。根据是否定义了业务流程逻辑(有状态的还是无状态的),一个给定的业务流程中可能包含一个或多个事务。

启动一个业务流程之后,该流程将参与调用方的事务;如果调用方没有事务,该流程将启动一个新事务。如果没有隐式或显式的事务边界,该流程将在单个事务内执行。

在第一个示例中,我们的业务流程将调用四个同步 XA 调用。该流程是同步的、无状态的。容器将管理这个事务。

WLI 简单事务

由于未定义任何隐式或显式事务边界,WLI 将自动在单个 XA 事务中运行整个流程。如果任何数据源出现问题(例如,如果一个数据库关闭,或者找不到 JMS 队列)并且未定义任何异常处理程序,则整个事务将回滚。

在 WLI 中构建业务流程时,将根据流程中阻塞元素的位置形成 隐式事务 边界。向业务流程中添加节点时,业务流程内的事务边界将更改。

隐式事务 之所以是隐式 的,是因为其行为是由业务流程逻辑自动确定的,而且它们在流程图中是不可见的。

隐式事务 边界基于流程中阻塞元素的位置形成。向业务流程中添加流程节点时,这些边界将更改。此外,默认情况下业务流程是无状态的,更改事务边界的阻塞元素可以将该流程更改为有状态的。

以下节点将在 WLI 内更改业务流程中的事务行为:

  • 任何接收(阻塞)节点(Client Request 或 Control Receive 节点)
  • Parallel 组节点
  • Event Choice 节点
  • 在现有边界内添加一个或多个节点不会对现有事务边界造成影响,这些节点本身不会强制实施事务边界。

下面将阐释一个包含隐式事务的业务流程示例。Control Receive 节点是该业务流程中的一个阻塞元素,因此将创建一个新事务

隐式事务

此外,WLI 能够通过在 WLI 面板中使用“Transaction”节点来显式定义事务。这使得开发人员能够对事务边界中的某些节点进行分组,并且进行局部回滚,不会影响隐式流程事务。通过将“Transaction”节点加入上面的简单示例中,可以执行两个截然不同的事务,而不是一个。下图显示了在一个事务中进行头两个数据库更新,在另一个事务中将 JMS 加入队列中并进行第三个数据库更新。

WLI 显式事务

通过在 WLI 流程中显式指定事务作用域,我们强制 WLI 完成打开的事务(此处的事务不嵌套)并开始一个新事务。如果我们在事务作用域显式结束后添加其他步骤,这些步骤可能还会开始它们自己新的隐式 XA 事务。WLI 中不支持嵌套事务。

如果 WLI 流程是一个无状态流程(同步或异步),它将始终在一个且仅一个隐式事务中执行。不能在同步流程或无状态异步流程中定义显式事务。因此,参考上述示例,只需将 Transaction 节点添加到一个无状态的流程中,即可将其转换成一个有状态流程。

此外,以下限制适用于显式事务:

  • 所选节点必须是连续的
  • 所选节点不能包括 Client Request 或 Control Receive 节点
  • 所选节点不能包含在同步流程的 Client request/response 节点中
  • 所选节点不能包括 Parallel 或 Event Choice 组节点,如果显式事务中包括这两个组节点,会将事务嵌套为它们的分支
  • 所选节点不能包含在现有显式事务中

有关 WLI 中事务处理的更多信息,请参阅

在 BPEL PM 中实施流程

在 BPEL PM 中,与 WLI 中一样,每个 BPEL 流程在一个或多个事务环境中执行。当一个流程开始执行时,流程管理器对流程执行以下操作之一:

  1. 它针对该流程启动一个新事务。
  2. 它将该流程加入一个已打开的事务中。

BPEL 使用该事务更新数据库的流程状态(这称作“脱水”),并将审计事件记录在数据库中。即使所有这一切都关闭,流程管理器仍将在事务环境中执行流程。通过 Web 服务接口调用时,BPEL 将采用第一种方法,因为没有可用的事务环境。在事务环境中通过 Java API 调用时,流程管理器可以采用以上任何一种方法,这取决于调用中使用的参数。

BPEL 将尝试将尽可能多的活动放入一个事务中。实际上,只有少数几个活动会导致流程管理器更新数据库中的流程状态并提交事务。给定的活动并不总是导致提交事务:有时,由于与活动相关联的属性,流程可能会保持相同的事务环境。

在我们的简单示例中,默认的事务行为与 WLI 中类似。当实例化一个流程且没有当前事务环境时,将创建一个新事务。和 WLI 中一样,BPEL 中的某些活动将自然地描述 XA 事务并强制结束事务。这些活动将导致 BPEL 流程的状态静止到脱水存储。当流程从此类活动恢复时,将启动一个新事务。下图阐释了与上面相同的步骤,在 BPEL 中作为单个隐式事务实施。

BPEL 简单事务

要在 BPEL 中执行第二个用例,我们希望在其中将我们的事务分成两个不同的事务,我们需要专门结束第一个事务。这可以通过在一个 Java Exec 活动中使用“checkpoint”方法显式完成,如下所示。

<bpelx:exec name="checkpointJavaExec" language="java" version="1.4">
     <![CDATA[
     checkpoint();
     ]]>
</bpelx:exec>

除了“wait 和 receive”以及其他可导致脱水(将 BPEL 流程状态写入数据库并提交事务)的活动之外,还可以通过将目标合作伙伴链接上的 idempotent 属性设置为 false 在一次调用后提交事务。如果 idempotent 设置为 false,invoke 活动在执行后立即脱水并记录在脱水存储中。这将结束初始事务并启动一个新事务。下图显示了这是如何实现的。

当 BPEL 调用一个适配器(ESB 或同一个 BPEL 域中的另一个流程)时,可以将目标包括在同一个事务中,也可以启动另一个事务。此行为由合作伙伴链接中的 transaction 属性控制。如果 transaction 属性值设置为 participate,被调用方将加入当前事务中。如果 transaction 属性设置为任何其他值,被调用方将在另一个事务中执行。这对于确保在一个事务中包括多个数据库更新很有帮助,但也有弊端。

如果任何被调用方回滚事务,当前的 BPEL 流程状态也将回滚到上一次提交。如果一直没有提交并且通过同步交互调用该流程,该流程似乎将消失得无影无踪。为了将这种影响降至最低,数据库适配器将引发一个错误而不是回滚事务 — 如果这么做不会影响事务完整性。(基本上来讲,您可以进行一次数据库更新而不回滚,但如果您进行两次,错误将导致回滚。)

最后要了解的一件事就是:在 BPEL 中,flow 活动(用于指定并行执行的活动)实际上是顺序处理,除非它遇到一个将导致线程挂起的活动。这样效率很高,但会阻挠流中的一个用例成功,因为要并行执行多个操作以减少服务延迟。BPEL 提供 nonBlockingInvoke=true 合作伙伴链接属性,将导致调用一个同步服务(内部作为对一个异步服务的调用)。在内部,该流程等待 JMS 队列上的消息,这会导致事务完成。同时,将启动一个新事务来执行同步调用并将结果放入队列中。这就允许并行执行流的其他分支。

超越 XA:补偿事务

当所有资源都符合 XA 时,上述示例可以解决所有行为。如果存在不符合 XA 的活动,必须在流程中构建补偿事务。WLI 和 BPEL 都提供了通过使用异常处理程序来解决此问题的机制。

而且,BPEL 还包括了可调用的补偿事务概念。这与异常处理程序类似,是在作用域级别定义的。然而,只能由“Compensate”活动显式调用它。补偿旨在允许对无法参与事务的系统应用反向操作,或者在已经决定系统不应作为事务的一部分进行操作时应用反向操作。例如,Web 服务可能允许递减库存,但一个错误使其必须回滚流程。在这种情况下,补偿处理程序应定义为调用 Web 服务递增库存,从而有效地提供了一个反向事务。这就允许您定义回滚活动,并将它们与执行可能需要反向的操作的代码相关联。因为无需重做所有工作即可处理某些异常,所以非常有用。

如果一个作用域需要一个补偿处理程序,应通过将“idempotent”属性值设置为“false”将需要补偿的服务标记为非幂等性。这将导致 Oracle BPEL 流程管理器在调用非事务资源后启动一个新流程。

下图演示了一个使用补偿处理程序以及显式转发补偿模型的示例。请注意,第二个作用域中 catchAll 块中的显式调用,调用 <compensate>

要点和建议

WLI 和 BPEL PM 都管理全局 XA 事务,实例化流程时,这两个工具都启动一个隐式事务,WLI 和 BPEL 中类似的活动强制结束事务。但是请注意,与 WLI 不同,Oracle BPEL 流程管理器不仅允许一个异步有状态流程中发生多个事务,而且还允许在一个同步流程中定义这些事务。通过增加补偿,BPEL 提供了一种为非事务资源提供补偿事务的标准可靠机制。

BPEL 本质上是一种有状态的语言。Oracle BPEL 流程管理器使用 XA 事务管理该状态,允许 XA 事务扩展到活动的 BPEL 流程边界之外。

有关导致提交的一般规则非常简单,BPEL 流程将在以下活动之后提交事务并启动新事务:

  • receive — 除非它是流程中的第一个接收并通过“transaction=participate”属性(可能是通过将其标记为与调用流程中合作伙伴链接中相同的内容)调用流程,这种情况下,流程参与现有事务。
  • checkpoint() — 在 Java Exec 活动中调用
  • onMessage
  • wait — 对于每次短暂等待(2 到 3 秒钟),流程管理器不会提交事务。
  • onAlarm
  • invoke — 仅当合作伙伴链接是非幂等性时(可以用“idempotent”合作伙伴链接属性进行标记)。
  • End of process flow — 仅当流程没有参与调用方的事务时(receive 的必然结果)。

下表总结了执行不同活动时的事务状态。

活动 BPEL 流程中的
事务状态
目标流程或适配器中的
事务状态
接收 新建事务 N/A
接收,属性为“transaction=participate” 使用来自调用方的现有事务 N/A
调用同步流程 使用现有事务 新建事务
调用同步流程,合作伙伴链接属性为“transaction=participate” 使用现有事务 使用现有 BPEL 事务
调用同步流程,合作伙伴链接属性为“idempotent=false” 新建事务 新建事务
调用同步流程,合作伙伴链接属性为“nonBlockingInvoke=true” 新建事务 新建事务
调用异步流程 使用现有事务 新建事务
调用异步流程,合作伙伴链接属性为“transaction=participate” 使用现有事务 新建事务
调用同步流程,合作伙伴链接属性为“idempotent=false” 新建事务 新建事务
等待时间 < 几秒钟 使用现有事务 N/A
等待时间 > 几秒钟 新建事务 N/A
checkpoint() 新建事务 N/A
对所有并行活动使用现有事务 N/A

 


Kathryn Kathryn Holden 任职首席销售顾问,专攻 SOA 和集成技术。她在 Oracle 工作已达 3 年。加入 Oracle 之前,她曾经在 BEA 作为集成专家工作了六年。
Antony Antony Reynolds 是 Oracle 英国的中间件解决方案总监,他主要致力于将业务需求转换成技术解决方案并在中间件系列中满足这些需求。作为一位受欢迎的 SOA 和 Oracle 融合中间件方面的网志作者,Antony 已在 Oracle 工作 10 年,拥有在各种公司担任各种技术角色超过 20 年的 IT 经验。
Tejas Tejas Joshi 是 Oracle SOA 咨询部门的高级架构师。过去十年间,他参与设计了众多集成和 SOA 解决方案。他获得 2006 年“年度 EMEA 技术专家”和 2007 年“金星”奖,以表彰其在英国的大型企业集成项目中的杰出表现。

面向 WLI 用户的 SOA 套件概要系列将邀请 WebLogic Integration 专家与 SOA 套件专家,共同探讨和阐释如何在 Oracle BPEL 流程管理器中实施常见的 WLI 模式。查看本系列中的其他部分