dev2dev 首页 > 资源中心 > 技术文章
BEA AquaLogic Data Services Platform 2.1大数据量操作最佳实践
名词:文中的DSP通指BEA AquaLogic Data Services Platform 2.1 问题产生 BEA AquaLogic Data Services Platform 2.1服务器作为一个BEA WebLogic Server的应用程序运行。客户端应用程序会请求平台服务器事先准备的数据服务函数集合来得到数据集合,客户端可以通过Static Mediator APIs、Dynamic Mediator APIs来得到要访问的数据集。

图1 BEA AquaLogic Data Services Platform架构概览
其中,Static Mediator APIs方式更为常用一些,它不仅可以使程序员完全抛开底层数据细节的干扰,充分使用面向对象的方式操作编程,还可以充分利用IDE的代码自动补齐功能。而Dynamic Mediator APIs方式由于其灵活性和更加面向规范,因此,在项目实践中也是一个不错的选择。但是不管哪种方式,当数据服务返回的数据量过大时(具体根据硬件配置不同而异),系统往往会由于系统资源耗尽(如:内存)而崩溃。虽然我们可以以数据流的方式来操控数据服务结果集,但其复杂程度往往让人望而却步,那么有没有一种更好的方式处理数据服务结果集呢?
问题分析 我们知道,当我们通过Static Mediator APIs访问数据服务时,DSP引擎会将结果集以集物化为XMLBean对象,而当我们通过Dynamic Mediator APIs访问数据服务时,DSP引擎会将结果集物化为Data Service对象。这样我们就可以通过XMLBean或SDO对象来访问数据服务结果集。因此,我们可以看出,不管是哪种APIs,DSP都会将数据结果集进行物化。如果数据量比较大时,系统就会消耗大量系统资源存放物化的实例,当到达极限时,系统最终将会由于资源耗尽而造成服务请求失败。 因此,为避免这个问题,我们可以通过控制数据服务返回结果集大小来避免,也就是说,每次调用数据服务时,只返回用户真正需要的内容。本文将介绍如何通过数据翻页的方式来实现分段数据处理。
方案简介 要实现对数据的翻页,则需要在每个服务层次添加一些辅助功能,如下图:

说明:Physical Data Services:在这一层次,我们添加了记录数计算功能,也就是说计算所有的记录数,用来计算总的页码数。如果底层所有数据源是关系型数据库,并且它们之间的关系比较明确,我们可以直接用SQL的select count(..) …功能来得出记录总数。步骤如下:

连接数据源

输入用来计算记录数的SQL语句

自动生成Data Service
Canonical Data Service:如果数据源非常多样(不仅仅是数据库),并且数据源的关系比较复杂,我们只能通过其它数据服务来获得数据,这样我们就要自己编写XQuery函数来计算记录数。
例:
……
for $x in ns1:CUSTOMER()
group $x as $g by 1
let $count :=fn:count($g)
……
其中的group操作非常重要,它可以大大提供服务的性能,具体说明参见: http://e-docs.bea.com/aldsp/docs21/xquery/bestpractices.html 查找group
Logical Data Services:在这个层次,我们可以创建一个通用的数据服务用来计算页码,比如:Page.ds,然后为每个需要分页操作的数据服务添加一个页码计算函数,例如:getCustomerPageCount(…)、getOrderPageCount(…),如下图:

函数写法如下: declare function tns:getCustomerPageCount($page_size as xs:int) as element(ns0:page_count) {
for $cc in ns2:CountCustomer() – 上两步得到的计录总数
let $count := fn:data($cc/count)
let $page_count := fn:ceiling( $count div $page_size )
return
<tns:page_count>{fn:data($page_count)}</tns:page_count>
};
Application Data Services:在每个需要实现分页的数据服务中创建一个得到分页结果的函数,例如:getPagedCustomer(…),函数具体写法:
declare function tns:getPagedCustomers($page_number as xs:int, $page_size as xs:int) as element(ns1:CustomerProfile)* {
<ns1:CustomerProfile>
{
let $all := tns:getAllCustomers()/customer
let $rows := fn:subsequence($all, (($page_number * $page_size) - $page_size) + 1, $page_size)
return
$rows
}
</ns1:CustomerProfile>
};
参数: $page_number:当前页码 $page_size:每页记录数
说明:这里主要是通过DSP提供的fn:subsequence(…)函数实现。 
参数: $sourceSeq:数据集合 $startingLoc:切分起始点: $length:切分长度 返回:切分后的数据集合
总结:
BEA AquaLogic Data Services Platform 2.1的主旨是实现数据的“服务化”,也就是说服务是数据服务的核心,而对于大数据量的处理或是单纯的大数据展现,我们可以借助其它方式来实现。当然使用BEA AquaLogic Data Services Platform 2.1也是完全可以实现这种需求,但多少有点杀鸡用牛刀的感觉。对于大数据量的处理,我们往往通过两种方式,一是通过数据流的方式实现(将另文介绍),第二种就是本文所介绍的通过数据分页的方式实现。
| 作者简介 |
 牛秀元 |
牛秀元是(dev2dev ID: Guru),BEA系统(中国)有限公司技术顾问,曾任Business Objests技术顾问,合力思软件公司技术顾问 |
作者其它文章
|