BPEL 面向 WLI 用户的 SOA 套件概要

比较 WLI 数据库事件生成器与 Oracle 数据库适配器

作者:Nacho Lafuente 和 Miquel Lopez-Miralpeix

2009 年 4 月发布

本文相关下载:
 Oracle SOA Suite

[第 1 页] [第 2 页] [第 3 页]

Oracle 应用服务器适配器有三种类型:分别针对技术打包应用程序 以及原有应用程序

有几种即取即用的 Oracle AS 技术适配器:

  • 文件适配器
  • FTP 适配器
  • 数据库适配器
  • AQ 适配器
  • JMS 适配器
  • MQ 适配器
  • 电子邮件代理
  • HTTP 代理

BPEL PM 和适配器

所有与 BPEL 流程交互的服务都称为伙伴链接。BPEL PM 有一个用于 SOAP 伙伴链接的原生接口,但针对其他类型的交互使用适配器。在 BPEL 中,适配器服务的表示方式与任何其他伙伴链接相同。BPEL 流程与 SOAP 伙伴链接以及适配器伙伴链接的交互没有任何差别。

适配器的 BPEL PM 集群支持

重要的一点是适配器完全支持集群,从而为基础技术提供最适合的解决方案。主动-主动集群配置并不适用于所有适配器,因为基础技术不支持某个适配器(例如文件适配器:许多文件系统不允许控制并发性),所以 BPEL 适配器框架支持入站适配器服务的主动故障切换。可以通过向特定 JCA 激活代理中添加一个属性来实现这一点(在 bpel.xml 中,这是存储 BPEL 流程的所有伙伴链接和激活代理的文件),如以下示例所示:

<activationAgents>
  <activationAgent className="..." partnerLink="MyInboundAdapterPL">
    <property name="clusterGroupId">myBpelCluster</property>

集群中的 BPEL PM 服务器 (JVM) 可以跨 TCP/IP 子网边界定位,并且可以通过添加属性
clusterAcrossSubnet=true 实现这一点。

在集群组中,对于同一(例如文件)适配器激活代理(用于特定伙伴链接)的多个激活,将由此集群中的活动适配器框架的所有实例隐式、自动检测。将仅允许一个激活实际启动消息的读取或发布。适配器框架实例将从多个激活中选择一个,对于谁应该承担主激活责任是随机的。集群中的其他激活(实例)将启动热备用状态,而实际上并没有在 JCA 资源适配器上调用 EndpointActivation。

如果主激活在某一时刻没有响应,则将其手动停用;如果它崩溃/退出,则集群组的其余任何一个适配器框架成员会立即检测到这一情况,并且将主激活责任重新分配给一个备用激活代理。此特性使用下面的 JGroups 实现,因此具有 clusterGroupId 属性。

组合与拆分支持

用于文件的 Oracle AS 适配器、用于 FTP 的 Oracle AS 适配器以及用于数据库的 Oracle AS 适配器支持组合和拆分功能。用于文件的 Oracle AS 适配器和用于 FTP 的 Oracle AS 适配器都包括一个读取器,可将单个庞大的文件拆分为几批处理,从而允许选择最合适的消息大小。您需要在设计时配置期间指定每批的大小。此外,适配器还包括一个写入器,可将一组消息组合为单个文件。

用于数据库的 Oracle AS 适配器包括一个发布组件,可轮询一组表以检测事件。此组件可以向 BPEL 流程引发事件,每次一个记录或多个记录。

同样,可以使用批量写入通过一个调用将多个记录插入数据库。

用于数据库的 Oracle AS 适配器 (DBAdapter)

用于数据库的 Oracle AS 适配器将 Oracle Toplink 用作在 XML 数据(对象)和关系模式之间进行互相映射的技术。通常,无需编写 SQL 代码,并且大部分配置通过适配器向导完成。

由于采用此体系结构,因此可以支持任何符合 jdbc 的数据库,并且可以在流程级别、适配器级别提供连接详细信息或作为 JEE 容器数据源提供,从而能够与其他应用程序共享池。这就提供了非常灵活的连接管理,从而适合所有情况。

对于出站交互,提供了大量操作:

  • Insert,用于将新记录插入数据库。
  • Update,用于更新数据库中的现有记录。
  • Write,用于插入或更新记录而不关注记录是否存在。
  • Delete,用于从数据库中删除记录。
  • Merge,首先在数据库中读取相应记录,计算任何更改,然后执行最少更新。
  • Select,用于在给定条件下查询记录。可以将数个查询定义为单独操作。
  • 纯 SQL,允许绕过 TopLink 执行任意 SQL。SQL 进行自我检测并在向导中执行,从而在您键入时生成匹配的 XSD(也可编辑)。
  • QueryByExample,与 SELECT 操作不同,不需要在设计时指定选择条件。
  • 过程函数 执行。

对于入站交互,轮询策略如下:

  • 物理删除 策略轮询数据库表以获得记录,并且在处理后删除。
  • 逻辑删除 策略更新每个已处理行上的特定字段,并且在运行时更新 WHERE 子句以筛选出已处理的行。
  • 序列表:最后读取的 ID 策略使用帮助器表记住序列值。
  • 序列表:最后更新 策略使用帮助器表记住最后更新的值。
  • 控制表轮询 策略使用控制表存储尚未处理的每行的主键。可以通过在单独的数据库上创建 SEQUENCING_HELPER 表使此轮询方法变得完全不可侵入。不对源表或其模式进行修改,仅针对源表执行的 DML 语句是轮询选择。无需创建带触发器的影子表(像 WLI 中的事件生成器所做的那样)。此轮询方法还支持轮询子更新。例如,如果 Order 和 LineItem 都包含 last_updated 列,则向现有 Order 中添加新的行项目时,可能再次选择并处理 Order。

示例:

某公司每次聘用新员工时都需要启动一个业务流程。将员工信息存储在 Oracle 数据库的一个表中。该业务流程将使用 BPEL PM 实施,并且只需要员工标识即可继续。

应该使用 DBAdapter 检测对员工表执行的插入。可以使用序列表或控制表轮询策略,我们选择后者,因为它与 WLI 最为类似。必须创建控制表,其中将包含员工的主键列。应该在员工表上创建一个触发器,以便每次创建一个员工时就在控制表中插入一条记录,然后将 DBAdapter 配置为轮询该控制表,从中读取该控制记录及其“子项”(实际员工记录)。最后,可以对控制表应用任何其他策略,以便避免重新处理该员工。

在设计时,用户可以导入多个相关表。DBAdapter 将搜索所有外键并为用户提供可供选择的所有可能关系。用户还可以使用逻辑约束在向导中为自己的关系建模。

生成的 XML 结构是嵌套结构,以选定的表作为根 Xml 元素,以联接的表作为子类型和集合。

下面是此类数据结构的一个示例:

   <xs:complexType name="Departments">
      <xs:sequence>
         <xs:element name="departmentId" type="xs:int"/>
         <xs:element name="departmentName" minOccurs="0">
            <xs:simpleType>
               <xs:restriction base="xs:string">
                  <xs:maxLength value="30"/>
               </xs:restriction>
            </xs:simpleType>
         </xs:element>
         <xs:element name="locationId" type="xs:int" minOccurs="0" nillable="true"/>
         <xs:element name="manager" type="Employees" minOccurs="0" nillable="true"/>
         <xs:element name="departmentCollection" minOccurs="0">
            <xs:complexType>
               <xs:sequence>
                  <xs:element name="Employees" type="Employees" minOccurs="0" 
maxOccurs="unbounded"/>
               </xs:sequence>
            </xs:complexType>
         </xs:element>
      </xs:sequence>
   </xs:complexType>

在此数据结构中,我们可以看到一个类型为 Employees、名为 manager 的元素,表示部门和员工之间的 N:1 关系;另一个名为 departmentCollection 的元素,表示一个员工列表,它表示了部门和员工之间的 1:N 关系。

正如看到的那样,BPEL PM 原本总是用于 XML 结构,它是执行到 SQL 类型和命令转换的适配器。

示例:

某网上商店每次在系统中下订单时都需要启动一个业务流程。订单信息将分散到 Oracle 数据库的不同表中。一个表存储订单项目;另一个表存储每个项目的物理位置;最后,再一个表存储常规订单信息。该业务流程将使用 BPEL PM 实施,并且需要这三个表中的信息才能继续。业务流程应该只在订单中的标记设置为“ready”状态时才启动。执行 BPEL PM 业务流程之后,此标记应该更改为“done”。

最好的方法是创建两个伙伴链接(一个用于入站,另一个用于出站):

1) 逻辑删除策略轮询服务,然后选择具有标记列的表作为根表,其余的表将通过关系进行添加。最后,选择“ready”值作为表示未读取的值,并且创建一个新值(如“in-process”)作为已读取(已经检索但流程尚未结束)。

2) 流程结束时,我们应该使用出站 DBAdapter 服务的合并操作将标记值更改为“done”。

下图表示数据库适配器体系结构的逻辑视图。

入站 DBAdapter 遵循以下过程:

  • 根据计划(可以配置)激活
  • 根据轮询策略激活 处理器。
  • 对于任何策略,可以设置以下参数:
    • 线程数(自 10.1.3.1 开始)
    • 每次读取时从数据库检索的最大行数
    • 可向 BPEL 作为一个信息发送的最大行数
    • 批量删除行 — WLI 中没有此特性。

DBAdapter 高级概念

DBAdapter 配置

高级配置信息在用于文件、FTP、数据库以及企业消息处理的 Oracle® 应用服务器适配器用户指南中进行了解释。请仔细阅读有关适用于 DBAdapter 的不同设置的信息。

消息结构

DBAdapter 伙伴链接遵循在设计时生成伙伴链接时定义的 XML 模式来发布(入站)和接收(出站)消息。从 BPEL 流程的角度看,针对常规 SOAP 伙伴链接和 DBAdapter 链接进行的消息操作没有任何差别。

每个轮询和每个事件的最大行数

在 DBAdapter 中,每个轮询和每个事件的行数可以通过以下设置进行控制:

  • NumberOfThreads:读取数据库的并发线程的数量。
  • MaxTransactionSize:在一个事务中从数据库提取到适配器的最大行数。
  • MaxRaiseSize:作为一个消息从适配器发送到 BPEL 的最大行数。

事务处理行为

每个 BPEL 流程都是事务流程,并且 DBAdapter 也得益于此行为。对于入站交互,根据参数 deliveryPersistPolicy 的值(off.immediateon),检索和删除流程将作为 BPEL 流程事务的一部分或者将具有自己的事务。

如果 deliveryPersistPolicy 设置为 on(默认值),则消息由传送服务 (DS) 保存,并且将由 MDB 线程处理(一旦某线程可用于执行此操作)。

如果 deliveryPersistPolicy 设置为 off.immediate,则消息将不会由 DS 保存,并且适配器线程也将执行 BPEL 流程。如果因为平台问题而无法处理消息,则回滚事务,然后下次重新读取。WLI 中没有此特性 — 始终将处理拆分为消息检索(一个线程)和随后的消息处理(使用异步激活的另一个线程)。

这为调整 BPEL 流程提供了大量灵活性,因为我们可以在需要时减少数据库流量,但不会降低可靠性。

出站交互将在 BPEL 流程事务内进行处理。必须考虑如何定义 JEE 容器级别的数据源(全局或本地事务),以及正在执行的数据库过程或函数是否包括 COMMIT 或 ROLLBACK,这点非常重要。

用例示例

在 WLI 中实现用例

创建流程应用程序

为了能够执行本文中包含的 WLI 示例,您必须先创建一个流程应用程序并将其部署到 WebLogic Integration 域。有关域创建过程,请参阅“使用配置向导创建 WebLogic 域”。

要创建流程应用程序,只需执行以下步骤:

  1. 访问 Oracle Workshop for WebLogic;
  2. 右键单击 Package Explorer 的空白区域并选择 New | Project
  3. New Project 屏幕中,展开 WebLogic Integration 并选择 Process Application
  4. 单击 Next。
  5. 输入以下内容:
    1. EAR Project Name:DatabaseEGEAR
    2. Web Project Name:DatabaseEGWeb
    3. Utility Project Name:DatabaseEGUtility
    4. 选中复选框 Add Weblogic Integration System and Control Schemas to Utility Project
  6. 单击 Finish

添加示例数据库模式

需要示例数据库以全面说明 WLI 如何检测和处理数据库事件。此用例已经使用具有预加载人力资源模式的 Oracle 10g 快捷版 (XE) 进行了设计。您还可以使用其他不缺少任何功能的数据库或模式。

WLI 需要找到将从其中接收事件的数据库模式。在配置任何数据库事件生成器之前,应至少创建一个数据库池。

创建 JDBC 数据源介绍了如何使用 WebLogic 管理控制台创建 JDBC 数据源。此示例已经使用 Oracle Thin/XA 驱动程序(引用已经随 Oracle 10g XE 一起提供的人力资源 (HR) 模式)创建了一个名为 databaseEGPool 的数据库池。

创建 WLI 流程以处理数据库事件

将创建一个示例 WLI 流程以处理数据库中生成的事件。此流程只显示事件接收,而不执行其他处理。创建一个名为“databaseeg”的新程序包。此程序包将在“DatabaseEGWeb”项目的“Java resources”文件夹内部创建。

  1. 单击“DatabaseEGWeb”项目以显示可用子文件夹列表。
  2. 展开“Java Resources”
  3. 右键单击“src”文件夹并从弹出菜单中选择 New > Package
  4. 将程序包命名为“databaseeg”并单击 Ok。

此流程将通过消息代理通道激活,因此需要创建新的通道定义。通道定义将在新近创建的“DatabaseEGWeb”项目的“databaseeg”Java 程序包内创建。

  1. 浏览“DatabaseEGWeb”项目并展开 Java Resources > src > databaseeg
  2. 右键单击程序包文件夹“databaseeg”并从弹出菜单中选择 New > Channel Definition
  3. 输入“DatabaseEG.channel”作为通道定义文件名
  4. 编辑通道定义文件以创建一个名为“SimpleXml”的简单 XML 通道。将不设置此通道的类型。以下代码段显示通道定义。
<?xml version="1.0"?>
<channels xmlns="http://www.bea.com/wli/broker/channelfile"
channelPrefix="/DatabaseEventGenerator"
xmlns:eg="http://www.bea.com/wli/eventGenerator"
xmlns:dp="http://www.bea.com/wli/control/dynamicProperties">
       <!- A simple channel passing XML ->
       <channel name ="SimpleXml" messageType="xml"/>
</channels>

创建通道定义之后,您就可以开始创建处理数据库事件的新 WLI 流程了。

  1. 右键单击程序包文件夹“databaseeg
  2. 选择 New > Process
  3. 输入“DatabaseEG”作为流程名

下图显示了生成的空 WLI 流程。

消息代理通道上收到消息时,将激活此流程。

双击 start 节点显示一个对话框,此对话框将用于为此流程选择首选启动器。选择“Subscribe to a Message Broker Channel...”。

双击 start 节点并选择“General Settings”选项卡。选择先前创建的通道定义 /DatabaseEventGenerator/SampleXml 作为此流程将监听的通道名。