使用 IBM BPM Advanced Integration Service 开发分布式 WS-AT 事务,第 4 部分: 实现 Advanced Integration Service

本文章系列介绍了如何利用 IBM Business Process Manager V8.0.1 Advanced 中的 Advanced Integration Services (AIS) 功能实现一个分布式 WS-AT 场景,该场景涉及两个不同的数据库(Microsoft® SQL Server 和 IBM® DB2®),它们安装在两个不同的机器上,可通过两个 Web 服务对它们进行访问:一个使用 .NET 实现,另一个使用 JEE 实现。该实现演示了一些自动回滚功能,这些功能由 AIS 中基于 SCA 的管理与 WS-AT 协议协同提供。在第 4 部分中,您将学习如何为事务实现 AIS。

Carlo Randone, 认证 IT 架构师 , IBM

Carlo Randone 是位于意大利的 IBM 全球企业咨询服务部的一名 IBM 认证 IT 架构师和 Open Group Master 认证 IT 架构师。Carlo 拥有在异构环境和操作系统上使用不同开发平台和中间件的丰富知识。作为一位经过认证的培训师和软件开发人员,他曾为一家 Microsoft® 认证的合作伙伴工作多年。

自 2000 年加入 IBM 以来,Carlo 的主要工作兴趣涉及 SOA 和 BPM、与它们相关的软件工程方法和支持平台,以及企业架构规划和设计。他喜欢收集与 IT 的历史发展相关的文档和硬件零部件,而且为了支持这一爱好,他成为了 Charles Babbage Institute 的一员。



Marco Antonioni, 认证 IT 架构师, IBM

Marco Antonioni 是位于意大利的 IBM 全球企业咨询服务部的一位经过认证的 IT 架构师和 Open Group Master 认证的 IT 架构师。Marco 拥有各种 WebSphere 平台(WebSphere Application Server、WebSphere Process Server、IBM Business Process Manager、IBM Operational Decision Manager、IBM Business Monitor、WebSphere Service Registry and Repository 和 WebSphere Message Broker)方面的深厚知识。自 2000 年加入 IBM 以来,他担任的主要职位是 IBM WebSphere 软件服务部的 BPM 解决方案架构师。



2014 年 1 月 09 日

在 Integration Designer 中实现 AIS

本系列的第 4 部分将指导您实现所设计的 Advanced Integration Service (AIS),以便在一个基于 SCA 的 ESB 中介中调用两个事务 Web 服务。此演示的工作区是在 KBPM-Main.zip(可从本系列的 第 1 部分 中下载)中定义的。

如文章 使用 IBM Business Process Manager Advanced 将业务流程和企业服务链接在一起 中所述,属于 Advanced Integration Service 有些用词不当:因为 IBM BPM V8 中的 AIS 提供了定义一个服务的单个操作的能力,所以真正提供的是一个 “AIS 操作”。在服务设计练习中,一个逻辑服务可能带来许多相关的 AIS 定义,每个定义对应一个操作。在本文中描述的场景中,AIS 公开了执行转账的事务操作。

解决方案的装配图

图 1 显示了建议解决方案的装配图。主要组件包括:

  • AIS 入站 Export TxWSAIS,具有接口 TxWSAIS。
  • TxMediation 中介,具有接口 TxWSAIS 和两个出站 Imports:
    • IWSChargeBank1SvcImport(接口 IWSChargeBank1Svc,具有 Charge 操作)连接 WSChargeBank1Svc Web 服务。
    • IWSCreditBank2SvcImport(接口 IWSCreditBank2Svc,具有 Credit 操作)连接 WSCreditBank2Svc Web 服务。
图 1. AIS 实现的装配图
AIS 实现的装配图

两个 Web 服务 Imports 的绑定属性包含被调用的 Web 服务(图 2 和 图 3)的地址。

图 2. IWSChargeBank1SvcImport 的绑定
IWSChargeBank1SvcImport 的绑定
图 3. IWSCreditBank2SvcImport 的绑定
IWSCreditBank2SvcImport 的绑定

TxWSAIS 接口(如 图 4 中所示)是 AIS 的接口,是基于 BPMN 的实现(在 IBM BPM Process Designer 中建模)和 IBM Integration Designer 中的 AIS 技术实现(ESB 中介模块)之间的实际接口。

图 4. TxWSAIS 接口
TxWSAIS 接口

可以看到,包含输入参数(以触发事务)、输出参数 (OutputMessage) 和支持传输一个 ErrorMessage 字符串的 Fault 节。

您需要配置以下 SCA 事务限定符,以支持两个 Web 服务(WSChargeBank1Svc 和 WSCreaditBank2Svc)参与同一个全局事务上下文(由中介模块发起),如 图 5 中所示:

  • 将两个参与接口 ICharge 和 ICredit 上的 Join transaction 设置为 true
  • 将两个引用 IChargePartner 和 ICreditPartner 上的 Suspend transaction 设置为 false
  • 将以下实现的 Join transaction 设置为 True
    • TxMediation:Interfaces、TxWSAIS 和 invoke
    • IWSChargeBank1SvcImport:Interfaces、IWSChargeBank1Svc 和 Charge
    • IWSCreditBank2SvcImport:Interfaces、IWSCreditBank2Svc 和 Credit
  • 将 TxMediation 实现的 Transaction 设置为 Global
  • 将 TxMediation References IWSCreditBank2SvcPartner 和 IWSChargeBank1SvcPartner 的 Suspend transaction 设置为 False
图 5. 事务限定符
事务限定符

IBM BPM Advanced 使用 WebSphere Application Server 中的事务管理器作为其事务的基础。对于一个中介模块,可为整个模块配置事务边界。在我们的示例中,我们需要这样一种配置,其中两个参与的 Web 服务(WSChargeBank1Svc 和 WSCreditBank2Svc)位于中介模块的同一个事务上下文中,“加入” 全局事务上下文。为中介模块和调用的服务指定的 SCA 事务限定符必须配置为启用全局事务传播。

IWSCreditBank2Svc 和 IWSChargeBank1Svc 接口(具有相关的 Credit 和 Charge 操作)如 图 6 和 图 9 中所示。

图 6. IWSCreditBank2Svc 接口和 Credit 操作
IWSCreditBank2Svc 接口和 Credit 操作

Credit 和 CreditResponse 类型的结构如 图 7 和 图 8 中所示。

图 7. Credit 类型
Credit 类型
图 8. CreditResponse 类型
CreditResponse 类型
图 9. IWSChargeBank1 接口和 Charge 操作
IWSChargeBank1 接口和 Charge 操作

两个 Credit 和 Charge 操作的 Input 和 Output 参数分别对应于两个 Web 服务的实现中的 Credit 和 Charge 方法的签名,这两个 Web 服务为 WSCreditBank2Svc(在 Java 中使用 JAX-WS 实现)和 WSChargeBank1Svc(在 C# 中使用 .NET WCF 实现):

public String credit(String myConnection, String myTable, String myAccount, Integer myAmount))

public string Charge(string myConnection, string myTable, string myAccount, int myAmount)

Integration Designer 中的 SCA ESB 中介模块

本文中描述的场景中使用的 AIS 是使用一个(在 IBM Integration Designer 中实现的)基于 SCA 的中介模块来实现的。仲裁(mediation)是一种在服务之间进行仲裁或动态干预的方式。一个中介流实现一个中介模块。

仲裁具有多种有用的功能。例如,在需要将数据从一个服务转换为可供另一个服务接受的格式时,可以使用仲裁。您可以使用日志来记录来自一个服务的消息,然后再将它们发送到下一个服务。可使用路由来将数据从一个服务路由到中介流所确定的一个合适服务。

也可使用仲裁功能来映射接口。接口可能拥有不同的操作名称,这些操作可能也拥有不同的参数类型。一个接口映射对各个操作和这些方法的参数建立映射,以便解决差异并使这两种组件可以交互。一个接口映射就像两个组件的接口之间的一座桥梁,允许它们连接在一起,尽管它们存在差异。

中介模块的操作与它所连接到的服务无关。在 IBM Integration Designer 中,组装编辑器中的一个中介模块显示为导出和导入之间的一个中介流组件。一个中介流是使用中介流编辑器创建的一种结构。在组装编辑器中选择一个中介流组件时,会自动打开中介流编辑器。在中介流编辑器中,来自一个服务的一个操作(服务请求或导出)会映射到另一个服务的操作(服务提供程序或导入)以及中介流编辑器所提供的功能。这些功能被称为中介原语,它们被连接到一个中介流中。您可以使用 IBM 提供的中介原语,或者创建自己的自定义原语。事实上,我们建议使用的解决方案中包含两个自定义中介原语。中介原语可同时处理消息内容和消息上下文,上下文是特定于绑定的信息,比如简单对象访问协议 (SOAP) 或 Java 消息服务 (JMS) 标头,或者用户定义的属性。

中介原语可通过终端连接到一起,这提供了中介原语的输入和输出点。所有中介原语都有一个输入终端(称为 in),可连接该终端来接受消息。大部分中介原语都有一个失败终端(称为 fail)和一个或多个输出终端。但是,停止和失败中介原语没有失败终端,也没有输出终端。

我们将执行向目标帐户(DB2 服务器 B 上的 Bank2 上)的贷入操作,然后在来源帐户(SQL Server A 上的 Bank1 上)执行扣费操作,以明确地展示如何在来源帐户上触发一次负值余额设置,以及如何触发服务器 A 上的一次本地回滚。我们将演示此回滚如何传播到整个分布式事务,导致已在服务器 B 上完成的实际的贷入操作被撤销(或者只是 “已准备” 并仍然等待一次最终提交),这得益于通过将 IBM BPM 中基于 SCA 的 AIS 实现与 WS-AT 协议相结合所带来的事务支持。

图 10 显示了 IBM Integration Designer 中的 TxMediationflow 的图解。

图 10. Integration Designer 中的 ESB 中介实现
Integration Designer 中的 ESB 中介实现

点击查看大图

图 10. Integration Designer 中的 ESB 中介实现

Integration Designer 中的 ESB 中介实现

这个中介流的两个核心元素是对 Credit 和 Charge 服务的两次调用,它们由服务调用中介原语(InvokeCredit 和 InvokeCharge)来实现。下面的组件(中介原语)列表定义了已实现并会在两种服务调用都得到积极结果时执行的操作流。在这种情况下,这里使用的不同类型的中介原语和采用的具体配置如下所示:

  • Input (invoke):Input 节点是请求流的起始点。它将来自来源操作的消息发送到请求流。
  • FanOut1(类型为 Fan Out):此场景中结合使用了 Fan Out 原语和 Fan In 原语来聚合或组合两个服务响应(来自 Credit 和 Charge Web 服务)。
  • FlowOrder1(类型为 Flow Order):允许该流的两个分支按输出终端上指定的顺序完成(Credit 操作在 Charge 操作之前完成)。
  • MapForCredit(类型为 Mapping):通过仅选择执行 Credit 操作所需的值,转换输入消息格式。
  • InvokeCredit(类型为 Service Invoke):调用 WSCreditBank2Svc Web 服务。
  • MsgElementSetterCredit(类型为 Message Element Setter):将 /body/CreditResponse/CreditResult 复制到 /context/shared/ResponseFromCredit 来支持(使用 Service Message Object 上下文)将来自 Credit 操作的结果传输到 Input Response 节点。
  • FromCreditToFanIn(类型为 Mapping):它是一个通往 Fan In 的简单路径。
  • MapForCharge(类型为 Mapping):通过仅选择执行 Charge 操作所需的值,转换输入消息格式。
  • InvokeCharge(类型为 Service Invoke):调用 WSChargeBank1Svc Web 服务。
  • MsgElementSetterCharge(类型为 Message Element Setter):将 /body/ChargeResponse/ChargeResult 复制到 /context/shared/ResponseFromCharge 来支持(使用 Service Message Object 上下文)将来自 Charge 操作的结果传输到 Input Response 节点。
  • FromChargeToFanIn(类型为 Mapping):它是一个通往 Fan In 的简单路径。
  • FanIn1(类型为 Fan In):允许将多条(使用 Fan Out 原语创建的)消息组合到一个聚合中。这个 Fan In 配置为在收到两条消息时触发输出终端。
  • PrepareOutputMsg(类型为 Mapping):它是一个中介模块,用于串联来自 Credit 和 Charge 操作的两个(积极)输出消息(这两条消息从 SMO 上下文中读取)。
  • Input Response (invoke):Input Response 节点是响应和请求流中的一个端点。它将已处理的消息作为响应返回给来源操作。

在两个服务调用(InvokeCredit 或 InvokeCharge)中的一个服务调用出现错误时,执行的操作流是不同的。后面的 Service Invoke 中介原语 中将会介绍,Service Invoke 中介原语拥有一个输入终端 (in) 和多个输出终端。未建模的故障有一个失败终端 (fail),每个已建模的故障有一个输出终端 (exception)。已建模的故障是在一个 WSDL 文件中显式列出的错误,其他任何故障都是未建模的故障。

Credit Web 服务可生成一个建模的异常故障(例如对于一个不存在的贷方帐户)或一个未建模的故障。在 InvokeCredit 中发生已建模的故障时,实现和执行的操作流(从 InvokeCredit 的输出终端 exception 开始)如下所示:

  • ManageCreditExc(类型为 mediation):从异常消息中提取错误信息,将此字符串复制到输出消息正文中的 InvokeFault1Msg 元素中。
  • SynchTxRollback(类型为 Synchronous Transaction Rollback):在以同步方式调用该流时(像我们的建议场景中一样),回滚当前的事务
  • Input Fault (invoke):作为请求流中的一个端点,Input Fault 节点为来源操作中定义的每个故障消息类型提供了一个输入终端。该错误消息存在于 invokeFault1Msg 中。

当 InvokeCredit 中发生未建模的故障错误时,实现和执行的操作流(从输出终端 fail 开始)如下所示:

  • ManageCreditFail(类型为 custom mediation):从上下文提取错误信息,并将此信息复制到输出消息正文中的 InvokeFault1Msg 元素中。
  • Input Fault (invoke):该错误消息存在于 invokeFault1Msg 中。

Charge Web 服务只能在 InvokeCharge 中生成未建模的故障。以下是在发生一个错误时的流程(例如,如果一个扣费帐户不存在或资金不可用),从 InvokeCharge 的输出终端 fail 开始:

  • ManageChargeFail(类型为 custom mediation):从上下文提取错误信息,并将此信息复制到输出消息正文中的 InvokeFault1Msg 元素中。
  • Input Fault (invoke):该错误消息存在于 invokeFault1Msg 中。备注相同。

请注意,在 InvokeCredit 中出现一个已建模的故障时,需要一次显式的事务回滚(使用 Synchronous Transaction Rollback 类型的 SynchTxRollback 中介)。另一方面,未建模的故障会导致全局事务自动回滚。


解决方案中的中介原语类型

在前面描述的数据流中,使用了不同类型的中介原语。本节介绍此场景中使用的原语类型的主要特征。

Fan Out 和 Fan In 中介原语

可使用 Fan Out 中介原语从输入消息中的一个重复元素创建不同的消息。也可结合使用它和 Fan In 中介原语来聚合或组合服务响应。我们的事务场景中利用了第二种模式。

Fan Out 中介原语拥有一个输入终端 (in)、两个输出终端(out 和 noOccurrences),以及一个失败终端 (fail)。连接 in 终端来接受一条消息,连接其他终端来传播一条消息。

在默认模式中,out 终端用于传播输入消息,该终端仅触发一次。如果在一个 Fan Out 中介原语之后使用了一个 Fan In 中介原语,那么您可以聚合来自两次或多次服务调用的响应;在一个 Fan Out 和一个 Fan In 之间发生的一组中介原语被称为一个聚合块。这正是我们的场景中采用的模式。

如果一个聚合块包含多个分支上的 Service Invoke 中介原语,并且 Service Invoke 原语被配置为同步调用,那么(像我们的场景中一样)Service 调用将是同步的,并且特意未引入并行性。

可以使用 Fan Out 和 Fan In 中介原语,将来自两次服务调用的响应聚合到一个输出消息中,就像我们的场景中所做的那样。

SMO 的共享上下文区域用于存储一个 Fan Out 原语与一个 Fan In 原语之间的聚合数据。

Fan In 中介原语用于组合多条消息,您可以使用 Fan Out 中介原语创建这些消息。Fan In 中介原语接收消息,直到到达一个决策点,然后将收到的最后一条消息传播到输出终端。支持 3 种类型的决策点:

  • 简单计数:在输入终端上收到设定数量的消息后,Fan In 中介原语会触发输出终端。Fan In 输出终端的触发不会阻止 Fan Out 中介原语发送消息。因此,决策点可能到达不只一次,导致多次触发输出终端。这是我们的项目中采用的配置。
  • XPath 决策:如果输入消息的 XPath 计算结果为 true,那么 Fan In 中介原语会触发输出终端。
  • 迭代:Fan In 中介原语等待接收相应的 Fan Out 中介原语生成的所有消息,然后触发输出终端。

Fan In 中介原语有两个输入终端(in 和 stop)、两个输出终端(out 和 incomplete),以及一个失败终端 (fail)。连接输入终端来接受一条消息,连接其他终端来传播一条消息。in 终端接受输入消息,直到到达某个决策点,在这一点会触发 out 终端。没有 Fan Out 中介原语,Fan In 中介原语就无法使用。

Flow Order 中介原语

可使用 Flow Order 中介原语自定义数据流,指定要触发的输出终端。Flow Order 中介原语不会更改输入消息。

Flow Order 中介原语拥有一个输入终端 (in) 和任意多个输出终端。连接 in 终端来接受一条消息,连接其他终端来传播一条消息。

输出终端将会按照该原语中定义的顺序进行触发,每个分支完成之后,才能开始下一个分支。每个输出终端使用输入消息的未修改副本来触发。该数据流的每个分支完成之后,才会触发下一个终端。

在我们的场景中,FlowOrder1 用于在 Charge 服务之前调用 Credit 服务,以明确地演示 IBM BPM 中介模块与 WS-AT 协议一起实现的自动回滚功能。

Mapping 中介原语

在集成服务时,常常需要将数据转换为接收服务可处理的格式。Mapping 中介原语可用于将一种消息类型转换为不同的消息类型。它提供了一种简单机制,使用 XSLT 转换或业务对象映射来操作消息。您可以通过在输入和输出消息之间建立映射来更改 SMO 的标头、上下文或正文。

在我们的场景中,使用了这种中介原语来实现 MapForCredit、MapForCharge、FromCreditToFanIn、FromChargeToFanIn、ManageCreditExc 和 PrepareOutputMsg。

Message Element Setter 中介原语

可使用 Message Element Setter 中介原语提供一种简单机制来设置消息内容,它不会更改消息的类型。可以通过设置中介原语属性来更改、添加或删除消息元素。可使用 Target 属性将目标元素指定为 XPath 表达式。

在我们的场景中,使用了两个中介原语 MsgElementSetterCredit 和 MsgElementSetterCharge,以便分别使用对 Credit 和 Charge Web 服务的调用的积极成果在标头中设置一条消息。

Service Invoke 中介原语

可使用 Service Invoke 中介原语从一个中介流内部调用一个服务,作为在中介流末尾使用调出机制的一种替代方法。一个中介流中可拥有多个 Service Invoke 中介原语。因此,您可以拥有一系列服务调用。您可在请求或响应中介流中使用 Service Invoke 中介原语。

Service Invoke 中介原语拥有一个输入终端 (in) 和多个输出终端。未建模的故障有一个失败终端 (fail),每个已建模的故障都有一个输出终端。已建模的故障是在一个 WSDL 文件中显式列出的错误,其他任何故障都是未建模的故障。此外,还有一个输出终端 (out) 和一个超时终端 (timeout),该输出终端用于成功的服务调用,超时终端用于某些类型的异步调用。

在本文中描述的场景中:

  • Charge .NET Web 服务可能生成一个未建模的故障;在这种情况下,可能会激活 Service Invoke 的失败终端(随后执行一个自定义的中介,从返回的消息的上下文中提取错误信息字符串);这个未建模的故障自动在中介级别上触发一次事务回滚。
  • Credit JEE Web 服务可能生成一个异常(根据 Web 服务的 WSDL 中的定义,一个已建模的故障);在这种情况下,会激活 Service Invoke 的相应终端(随后执行一个标准的 Mapping 中介原语,从返回的 SOAP 消息提取错误信息字符串)。已建模的故障不会自动回滚全局事务,所以在这种情况下,中介流中有一个 Synchronous Transaction Rollback 中介原语。

请注意,Web 服务实现中有两个不同的选项,我们还选择了相关的不同错误公开模式,以演示处理中介流中的错误的不同方式。

developerWorks 文章 使用 IBM Integration Designer、WebSphere ESB 、WebSphere Process Server 和 Business Process Manager Advanced Edition 在中介模块中跟踪、记录日志并处理错误,第 2 部分 - Web 服务中介中的错误处理设计策略 详细描述了管理中介流中的错误的不同模式和技术。

Synchronous Transaction Rollback 中介原语

您可使用 Synchronous Transaction Rollback 中介原语回滚当前的事务,然后继续处理中介流。Synchronous Transaction Rollback 只能在使用了同步调用样式的中介流中使用,就像我们的场景中所做的那样。

如果希望在一个错误处理里程中显式回滚某个中介流中的当前事务,那么可以使用 Synchronous Transaction Rollback 原语。在我们的示例中,这个中介原语在 Credit Service Invoke 中存在一个已建模的故障时使用,用于显式回滚全局事务。

Custom Mediation 中介原语

可使用 Custom 中介原语在 Java 代码中实现您自己的中介逻辑。此原语将用户定义的中介原语的灵活性与预定义的中介原语的简单性相结合。可添加新终端并创建您自己的属性,这使您能够创建复杂的转换和路由模式。

在我们的场景中,自定义中介 ManageCreditFail 和 ManageChargeFail 用于从 Credit 或 Charge 服务调用返回的错误的上下文中提取错误信息(在发生未建模的故障时)。


中介流细节和中介原语配置

下面将介绍之前介绍的中介流中实现的主要配置。首先介绍 “快乐路径”,然后介绍错误路径。

快乐路径

  • MapForCredit(类型为 Mapping):这个原语用于准备适用于 WSCreditBank2Svc Web 服务调用的参数。 图 11 显示了实现的映射。我们可以看到,只有与 Credit 相关值传输到了服务调用。
    图 11. MapForCredit 中介
    MapForCredit 中介
  • MapForCharge(类型为 Mapping):这个原语用于准此调用 WSChargeBank1Svc Web 服务的参数。 图 12 显示了实现的映射。可以看到,只有与 Charge 相关值传输到了服务调用。
    图 12. MapForCharge 中介
    MapForCharge 中介

    点击查看大图

    图 12. MapForCharge 中介

    MapForCharge 中介
  • FanIn1(类型为 Fan In):在 FanIn1 属性中,一定要注意,输出端口仅在收到两条消息时才触发,如 图 13 中所示。
    图 13. FanIn1 配置属性
    FanIn1 配置属性
  • PrepareOutputMsg(类型为 Mapping):这个中介模块用于将来自 Credit 和 Charge 操作的两条积极输出消息串联起来(这两条消息从 SMO 上下文读取而来),如 图 14 中所示。
    图 14. PrepareOutputMsg 中介
    PrepareOutputMsg 中介

    点击查看大图

    图 14. PrepareOutputMsg 中介

    PrepareOutputMsg 中介

错误路径

Credit 和 Charge Web 服务(分别由 InvokeCredit 和 InvokeCharge 流活动调用)可抛出至少 3 种主要的典型异常,并由中介流管理或捕获:

  • 来源(用于 Charge)或目标(用于 Credit)银行帐户的帐户名称不可用。在这种情况下,Web 服务会抛出一个错误和消息 “Invalid account”。
  • 扣费帐户中没有足够的资金。在这种情况下,数据库上的触发器会抛出一个 “Insufficient money” 异常,Web 服务可再次将该异常抛出给调用方。
  • Web 服务捕获和重新发出的其他任何运行时错误(例如表名错误、JDBC 连接不可用、连接远程数据库引擎时发生网络错误,等等),以及相关的错误消息。

Credit Web 服务可生成一个建模的异常故障(例如对于一个不存在的贷方帐户)或一个未建模的故障。已建模的故障对应于 WSDL 接口中定义的错误。未建模的故障是未在 WSDL 接口中声明的错误。

在 InvokeCredit 中出现已建模的故障错误时,调用的两个中介模块是 ManageCreditExc(类型为 mediation)和 SynchTxRollback(类型为 Synchronous Transaction Rollback)。

ManageCreditExc 中介原语设计来从异常消息提取错误信息(一个字符串),并使用此字符串在 InvokeFault1 元素中生成一个输出正文,如 图 15 中所示。

图 15. ManageCreditExc 中介
ManageCreditExc 中介

点击查看大图

图 15. ManageCreditExc 中介

ManageCreditExc 中介

请注意,在 InvokeCredit 中发生已建模的故障时,需要使用 SynchTxRollback 中介执行一次显式的事务回滚;未建模的故障会导致一次自动事务回滚。

在 InvokeCredit 中发生未建模的故障错误时,存在一个 ManageCreditFail 中介(类型为 Custom mediation)。ManageCreditFail 类似于 ManageChargeFail 自定义中介,后者用于处理从 Service Invoke 到 WSChargeBank1Svc 的未建模故障。

清单 1 包含 ManageCreditFail 自定义中介的代码。

清单 1. ManageCreditFail 自定义中介的源代码
/**
 * GENERATED COMMENT - DO NOT MODIFY
 * Variables:  for output terminals - out (com.ibm.wsspi.sibx.mediation.OutputTerminal)
 *             for user properties - <No user properties defined>
 * Inputs:     inputTerminal (com.ibm.wsspi.sibx.mediation.InputTerminal), 
	smo (com.ibm.websphere.sibx.smobo.ServiceMessageObject)
 * Exceptions: com.ibm.wsspi.sibx.mediation.MediationConfigurationException, 
	com.ibm.wsspi.sibx.mediation.MediationBusinessException
 */

try
{
// fault parsing
javax.xml.parsers.DocumentBuilderFactory factory = 
	javax.xml.parsers.DocumentBuilderFactory.newInstance();
javax.xml.parsers.DocumentBuilder builder = factory.newDocumentBuilder();
String soapFault = smo.getContext().getFailInfo().getFailureString();
java.io.ByteArrayInputStream bis = new java.io.ByteArrayInputStream (soapFault.getBytes());
org.w3c.dom.Document document = builder.parse(bis);

String faultstring = "";

faultstring = 
	document.getElementsByTagName("faultstring").item(0).getChildNodes().item(0).getNodeValue();

com.ibm.websphere.sca.ServiceManager serviceManager = new com.ibm.websphere.sca.ServiceManager();
com.ibm.websphere.bo.BOFactory bofactory = 
	(com.ibm.websphere.bo.BOFactory)serviceManager.locateService("com/ibm/websphere/bo/BOFactory");

commonj.sdo.DataObject newbody = 
	bofactory.createByMessage("http://KBPM/AIS/TxWSAIS", "invokeFault1Msg");
newbody.setString("invokeFault1", faultstring);
smo.setBody(newbody);

out.fire(smo);

}
catch (Exception ex)
{
ex.printStackTrace();

Charge Web 服务只能在 InvokeCharge 中生成未建模的故障(这个 Web 服务不会在 WSDL 中公开故障)。在这种情况下,中介流将会到达 ManageChargeFail 中介。ManageChargeFail 类似于 ManageCreditFail 自定义中介,后者用于处理从 Service Invoke 到 WSCCreditBank1Svc 的未建模故障。

在发生错误时,必须从 Context/failInfo/failureString 结构中提取错误消息。failureString 是一个类似以下字符串的 XML 字符串:

<soapenv:Body 
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Fault>
<faultcode>soapenv:Client</faultcode>
<faultstring>Exception from Charge (-): 
	myConnection: Data Source=localhost; Uid=sa; Initial Catalog=Bank1; 
	Pwd=mypwd; strSQL: UPDATE dbo.Accounts SET Amount = Amount - 200 
	WHERE Description = &apos;Karl&apos;; ex.Message: Insufficient money.&#xd;
The transaction ended in the trigger. The batch has been aborted.
</faultstring>
</soapenv:Fault>
</soapenv:Body>

上面列出的 XML 载荷(完整的 failureString)最初通过以下代码获取:

String soapFault = smo.getContext().getFailInfo().getFailureString();

在以后,可使用以下代码从完整的 soapFault XML 字符串(上面理出的 XML 代码)提取简单的 faultstring:

点击查看代码清单

faultstring = document.getElementsByTagName("faultstring").item(0).getChildNodes().item(0).getNodeValue();

然后使用该 faultstring 在消息正文中建立答案,如下所示:

newbody.setString("invokeFault1", faultstring);
smo.setBody(newbody);

清单 2 给出了 ManageChargeFail 自定义中介的完整代码。

清单 2. ManageChargeFail 自定义中介
/**
 * GENERATED COMMENT - DO NOT MODIFY
 * Variables:  for output terminals - out (com.ibm.wsspi.sibx.mediation.OutputTerminal)
 *             for user properties - <No user properties defined>
 * Inputs:     inputTerminal (com.ibm.wsspi.sibx.mediation.InputTerminal), 
	smo (com.ibm.websphere.sibx.smobo.ServiceMessageObject)
 * Exceptions: com.ibm.wsspi.sibx.mediation.MediationConfigurationException, 
	com.ibm.wsspi.sibx.mediation.MediationBusinessException
 */
try
{
// fault parsing
javax.xml.parsers.DocumentBuilderFactory factory = 
	javax.xml.parsers.DocumentBuilderFactory.newInstance();
javax.xml.parsers.DocumentBuilder builder = factory.newDocumentBuilder();
String soapFault = smo.getContext().getFailInfo().getFailureString();
java.io.ByteArrayInputStream bis = 
	new java.io.ByteArrayInputStream (soapFault.getBytes());
org.w3c.dom.Document document = builder.parse(bis);

String faultstring = "";
faultstring = 
	document.getElementsByTagName("faultstring").item(0).
	getChildNodes().item(0).getNodeValue();

com.ibm.websphere.sca.ServiceManager serviceManager 
	= new com.ibm.websphere.sca.ServiceManager();
com.ibm.websphere.bo.BOFactory bofactory = 
	(com.ibm.websphere.bo.BOFactory)serviceManager.
	locateService("com/ibm/websphere/bo/BOFactory");

commonj.sdo.DataObject newbody = 
	bofactory.createByMessage("http://KBPM/AIS/TxWSAIS", "invokeFault1Msg");

newbody.setString("invokeFault1", faultstring);
smo.setBody(newbody);

out.fire(smo);
}
catch (Exception ex)
{
ex.printStackTrace();
}

有关 IBM BPM V8 with AIS 中的错误处理的出色的技术性描述,请参阅 IBM developerWorks 文章 在 IBM Business Process Manager Advanced V8 中配置 Advanced Integration Services 错误处理,对于 ESB 中介,请参阅 使用 IBM Integration Designer、WebSphere ESB 、WebSphere Process Server 和 Business Process Manager Advanced Edition 在中介模块中跟踪、记录日志并处理错误,第 2 部分


配置和应用事务策略集

除了在 WebSphere Application Server 上配置事务服务之外,您还需要执行以下步骤,为 Java Web 服务提供程序(Credit Web 服务)和 IBM BPM 中基于 SCA 的中介内的两个 Web 服务使用者启用该策略集。我们建议在 WebSphere 管理控制台中应用这些配置,同时也可以将它们应用在 Integration Designer 开发环境中。

创建和导出一个新的事务策略

  1. 在 WebSphere 管理控制台中,选择 Services => Policy sets => Application policy sets
  2. 单击 New,然后指定一个名称(例如 myWSTransaction)并将 WS-Transaction 添加到策略部分中。单击 OK 并保存更改。
  3. 导航到新创建的策略集上的 WS-Transaction 设置。为 WS-Atomic Transaction 选择 Mandatory 选项,如 图 16 中所示,然后保存更改。
    图 16. 配置新事务策略
    配置新事务策略

    点击查看大图

    图 16. 配置新事务策略

    配置新事务策略
  4. Application policy sets,选择新策略,然后选择 Export,将该新策略导出到一个文件中,比如 myWSTransaction.zip。可以使用这个文件在 Integration Designer 中导入和使用该策略。
  5. 重新启动 WebSphere Application Server。

将事务策略应用于 JAX-WS Credit Web 服务提供程序

使用 WebSphere 管理控制台应用该策略,如下所示:

  1. 选择 Services => Service providers
  2. 单击 Credit Web 服务的服务提供程序 (WSCreditBank2Svc)。
  3. 选择您的服务提供程序。
  4. 单击 Attach 并选择新策略,比如 myWSTransaction。
  5. 单击 Save

在 Integration Designer 中应用该策略,如下所示:

  1. 在 Integration Designer 中,在工作区中打开 WSCreditBank2Svc Web 服务。
  2. 从 File/Import,选择 WebSphere Policy Sets(在 Web services 类别中)。 File/Import 在哪里?这是不是一个菜单项?
  3. 选择包含从 WebSphere 管理控制台导出的事务策略的 zip 文件(例如 myWSTransaction.zip)。
  4. 单击 Finish
  5. 在 Services 视图中,展开 JAX-WS 并右键单击 WSCreditBank2Project{...}WSCreditBank2Svc
  6. 选择 Manage Policy Set Attachments/Server Side
  7. 将 myWSTransaction 策略添加到 WSCreditBank2Svc 服务。最终的配置应如 图 17 中所示。
图 17. 在 Integration Designer 中将事务策略添加到 Credit Web 服务
在 Integration Designer 中将事务策略添加到 Credit Web 服务

将该策略应用到 ESN 中介内的 Web 服务导入语句中

使用 WebSphere 管理控制台应用该策略,如下所示:

  1. 选择 Services => Service clients
  2. 选择服务客户端名称,比如 WSChargeBank1Svc(具有已部署的资产名称 KWSBPM-Tip-KWSBPMMediationModuleApp)。
  3. 选择 WSChargeBank1Svc
  4. Attach Client Policy Set 中,选择事务策略 (myWSTransaction),然后单击 Save
  5. 选择 Services =>Service clients
  6. 选择另一个服务客户端名称,比如 WSCreditBank2Svc(具有与 WSChargeBank1Svc 相同的已部署的资产名称 KWSBPM-Tip-KWSBPMMediationModuleApp)。
  7. 选择 WSCreditBank2Svc
  8. Attach Client Policy Set 中,选择事务策略 (myWSTransaction),然后单击 Save

在 Integration Designer 中应用该策略,如下所示

  1. 在 Integration Designer 中,在工作区中打开 Advanced Integration Service (KWSBPM Main) 实现。
  2. File/Import 下,选择 WebSphere Policy Sets(在 Web services 类别中)。
  3. 选择包含从 WebSphere Application Server 管理控制台导出的事务策略的 zip 文件(例如 myWSTransaction.zip)。
  4. 单击 Finish
  5. 打开 KWSBPMMediationModule 装配图。
  6. 单击 IWSChargeBank1SvcImport
  7. 在 Import 的属性中,单击 Policy Sets
  8. 选择事务策略 myWSTransaction 作为默认策略集。
  9. 在装配图中,单击 IWSCreditBank2SvcImport
  10. 在 Import 的属性中,单击 Policy Sets
  11. 选择事务策略 myWSTransaction 作为默认策略集。

结束语

本系列的第 4 部分介绍了如何以一个基于 SCA 的 ESB 中介模块为基础,通过调用两个事务 Web 服务在 Integration Designer 中实现事务 AIS。您学习了如何在 Integration Designer 中以装配图的形式设计 AIS,如何设计 ESB 中介流,如何配置接口和事务限定符,以及如何调用两个事务 Web 服务来处理两个数据库 Bank1 和 Bank2 上的数据。在本系列的最后一部分(第 5 部分中),您将学习如何执行和测试不同的事务场景,其中包含本系列前几部分中设计和开发的组件,您还将了解所实现的解决方案的 ACID(原子性、一致性、隔离性和耐久性)特征。


致谢

感谢同事 Giuseppe Bottura 和 Simone Chiucchi 审阅本文,感谢同事 Stefano Angrisano、Matteo Franciolli 和 Daniele Rossi 对本文所做的贡献。还要感谢 Andrew J. Howes、Billy Lo、Frank I. Toth、Dave Screen、Callum Jackson、Konstantin Luttenberger 和 Oliver Rebmann 提供富有启发性的、引人深思的 developerWorks 文章。

参考资料

学习

获得产品和技术

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=WebSphere
ArticleID=959735
ArticleTitle=使用 IBM BPM Advanced Integration Service 开发分布式 WS-AT 事务,第 4 部分: 实现 Advanced Integration Service
publish-date=01092014