面向 WLI 用户的 SOA 套件概要 比较 WLI 数据库事件生成器与 Oracle 数据库适配器作者:Nacho Lafuente 和 Miquel Lopez-Miralpeix 2009 年 4 月发布
Oracle 应用服务器适配器有三种类型:分别针对技术、打包应用程序 以及原有应用程序。 有几种即取即用的 Oracle AS 技术适配器:
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 子网边界定位,并且可以通过添加属性 在集群组中,对于同一(例如文件)适配器激活代理(用于特定伙伴链接)的多个激活,将由此集群中的活动适配器框架的所有实例隐式、自动检测。将仅允许一个激活实际启动消息的读取或发布。适配器框架实例将从多个激活中选择一个,对于谁应该承担主激活责任是随机的。集群中的其他激活(实例)将启动热备用状态,而实际上并没有在 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 容器数据源提供,从而能够与其他应用程序共享池。这就提供了非常灵活的连接管理,从而适合所有情况。 对于出站交互,提供了大量操作:
对于入站交互,轮询策略如下:
示例: 某公司每次聘用新员工时都需要启动一个业务流程。将员工信息存储在 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 遵循以下过程:
DBAdapter 高级概念DBAdapter 配置高级配置信息在用于文件、FTP、数据库以及企业消息处理的 Oracle® 应用服务器适配器用户指南中进行了解释。请仔细阅读有关适用于 DBAdapter 的不同设置的信息。 消息结构DBAdapter 伙伴链接遵循在设计时生成伙伴链接时定义的 XML 模式来发布(入站)和接收(出站)消息。从 BPEL 流程的角度看,针对常规 SOAP 伙伴链接和 DBAdapter 链接进行的消息操作没有任何差别。 每个轮询和每个事件的最大行数在 DBAdapter 中,每个轮询和每个事件的行数可以通过以下设置进行控制:
事务处理行为每个 BPEL 流程都是事务流程,并且 DBAdapter 也得益于此行为。对于入站交互,根据参数 deliveryPersistPolicy 的值(off.immediate 或 on),检索和删除流程将作为 BPEL 流程事务的一部分或者将具有自己的事务。 如果 deliveryPersistPolicy 设置为 on(默认值),则消息由传送服务 (DS) 保存,并且将由 MDB 线程处理(一旦某线程可用于执行此操作)。 如果 deliveryPersistPolicy 设置为 off.immediate,则消息将不会由 DS 保存,并且适配器线程也将执行 BPEL 流程。如果因为平台问题而无法处理消息,则回滚事务,然后下次重新读取。WLI 中没有此特性 — 始终将处理拆分为消息检索(一个线程)和随后的消息处理(使用异步激活的另一个线程)。 这为调整 BPEL 流程提供了大量灵活性,因为我们可以在需要时减少数据库流量,但不会降低可靠性。 出站交互将在 BPEL 流程事务内进行处理。必须考虑如何定义 JEE 容器级别的数据源(全局或本地事务),以及正在执行的数据库过程或函数是否包括 COMMIT 或 ROLLBACK,这点非常重要。 用例示例在 WLI 中实现用例创建流程应用程序为了能够执行本文中包含的 WLI 示例,您必须先创建一个流程应用程序并将其部署到 WebLogic Integration 域。有关域创建过程,请参阅“使用配置向导创建 WebLogic 域”。 要创建流程应用程序,只需执行以下步骤:
添加示例数据库模式需要示例数据库以全面说明 WLI 如何检测和处理数据库事件。此用例已经使用具有预加载人力资源模式的 Oracle 10g 快捷版 (XE) 进行了设计。您还可以使用其他不缺少任何功能的数据库或模式。 WLI 需要找到将从其中接收事件的数据库模式。在配置任何数据库事件生成器之前,应至少创建一个数据库池。 创建 JDBC 数据源介绍了如何使用 WebLogic 管理控制台创建 JDBC 数据源。此示例已经使用 Oracle Thin/XA 驱动程序(引用已经随 Oracle 10g XE 一起提供的人力资源 (HR) 模式)创建了一个名为 databaseEGPool 的数据库池。 创建 WLI 流程以处理数据库事件将创建一个示例 WLI 流程以处理数据库中生成的事件。此流程只显示事件接收,而不执行其他处理。创建一个名为“databaseeg”的新程序包。此程序包将在“DatabaseEGWeb”项目的“Java resources”文件夹内部创建。
此流程将通过消息代理通道激活,因此需要创建新的通道定义。通道定义将在新近创建的“DatabaseEGWeb”项目的“databaseeg”Java 程序包内创建。
<?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 流程了。
下图显示了生成的空 WLI 流程。 消息代理通道上收到消息时,将激活此流程。 双击 start 节点显示一个对话框,此对话框将用于为此流程选择首选启动器。选择“Subscribe to a Message Broker Channel...”。 双击 start 节点并选择“General Settings”选项卡。选择先前创建的通道定义 /DatabaseEventGenerator/SampleXml 作为此流程将监听的通道名。 |