IBM InfoSphere Master Data Management Server (MDM Server) 是目前市场内一个领先 MDM 解决方案。MDM Server 是一个物理的主存储库,可提供如顾客、产品、帐号等关键数据实体的实际情况。MDM Server 旨在满足高性能和可伸缩性要求。该产品为用来管理主数据的数据模型和业务服务提供了灵活定制。
该产品还能根据客户的需求进行定制。为了服务具有异构软硬件环境、客户业务需求和数据特点的客户群,每一种实现都拥有多个定制。重要的是,这些实现要遵循围绕每个定制的最佳实践,以便所做改变不会影响到 MDM Server 的行为。这将有助于客户更轻松地维护系统。
我们的目标是展示在 MDM Server 中编写可插入业务对象查询的最佳方式。可插入查询框架让我们可以修改由查询服务使用的现有数据库查询。为了确保服务经优化并且可以更快地运行来满足特定的性能目标,可能需要进行新的查询更改。本文使用了一个要求定制的示例场景,并给出了一个逐步的解决方式。由于 MDM 是在 J2EE 框架上构建的,因此它遵循的是 Java™ 标准,且设计时就考虑到了可重用性,对于更好的系统维护,也有了一些推荐的最佳实践。此外,本文还讨论了 MDM Server V9.0.x 中引入的查询级别增强。
InfoSphere MDM Server 中的一个重要定制选项是使用可插入业务对象查询框架。此特性可帮助修改 MDM service 所使用的现有查询并用一个经优化的查询替换它。通常,在实现期间,我们会看到过客户使用此特性来配置快速运行的查询以满足性能目标。
MDM 文档提供了实现可插入查询所要执行的高级步骤。本文将帮助识别有无对可插入框架的需求并用一个示例场景给出进行这个产品修改的详细步骤。
由于 MDM 业务对象类的设计已经考虑到了可重用性,而且与某个特定域有关的类也已经组合在一起,这些类的实现若出现问题将可能影响产品的行为并会导致不希望的后果。稍后要讨论的最佳实践将有助于简化可插入查询的维护,而同时又不影响核心的产品功能。
这里使用了如下的 IBM InfoSphere MDM Server 组件和版本:
- InfoSphere MDM Server V9.0.1
- 运行 WebSphere® Application Server V6.1.0.25 的应用服务器
- 运行 DB2® V9.5 Fixpack 4 的数据库服务器
使用 InfoSphere MDM Server 业务对象查询扩展框架,我们就可以修改现有的 MDM Server 查询来获得更好的性能。由于 MDM Server 的设计目标就是要能够在很多的客户环境内运转来满足不同的数据需求,因此会可能需要这种定制。如果某个特别的查询事务未满足所需的性能预期,客户就可以考虑修改由此产品执行的数据库查询。
除了来自模块 DWLCommonServices、DWLAdminServices 和 Code Table Services 的服务之外,所有的产品查询事务都具有可插入查询支持。
我们将以 “Severe degradation of SQL performance with complicated "OR" clauses on DB2 z/OS platforms” Technote 中推荐的一个业务对象查询实现为例。
以上提到的 Technote 是对 InfoSphere MDM
Server 修改建议,使用 DB2 on z/OS® 作为数据库服务器。在调用 getPartyRelationship 服务时,由于要在经常执行的
SQL 语句上进行表扫描的原因,DB2 z/OS 在 I/O 和 CPU 方面的消耗成本很高。这是因为在开箱即用的默认查询内使用了一个复杂的 OR 语句。
为了解决这个问题,我们可以使用一个经优化的 SAL 语句修改默认查询,其方法是通过实现 MDM Server 的可插入的业务对象查询特性。下一节将涵盖要遵循的详细步骤和最佳实践。
在本样例场景中,我们需要定制现有的可插入查询,因为我们只会修改 getPartyRelationship 事务期间运行的那个查询:
- 扩展
BObjQuery类 - 覆盖现有查询
- 扩展
BObjQueryFactory实现类 - 注册新的 factory 实现类
在识别了所需的高级定制任务后,让我们来详细地逐一介绍每个步骤。
1. 扩展 BObjQuery 类
为了扩展此核心业务对象的查询实现,让我们创建一个名为 CustomPartyRelationshipExtBObjQuery 的新类。它会覆盖 provideSQLStatement(),所以它能在 getPartyRelationship 事务执行时,返回一个正确的查询。
清单 1. 显示经扩展的
BObjQuery 类的样例代码
package com.custom.tcrm.coreParty.bobj.query;
public class CustomPartyRelationshipExtBObjQuery extends PartyRelationshipBObjQuery {
public CustomPartyRelationshipExtBObjQuery(String queryName,
DWLControl control) {
super(queryName, control);
}
public CustomPartyRelationshipExtBObjQuery(String persistenceStrategyName,
DWLCommon objectToPersist) {
super(persistenceStrategyName, objectToPersist);
}
@Override
protected String provideSQLStatement() throws BObjQueryException {
return super.provideSQLStatement();
}
}
|
2. 覆盖现有查询
接下来,我们定义一个字符串参数来保存这个新的 SQL 语句。用如下的 SQL 语句定义一个新的字符串变量。
清单 2. 在
BObjQuery 类中声明的修改后的 SQL 语句private static final String CUSTOM_PARTY_RELATIONSHIPS_ACTIVE_QUERY = "SELECT CONTACTREL.CONT_REL_ID, CONTACTREL.REL_TP_CD, CONTACTREL.REL_DESC, CONTACTREL.START_DT, CONTACTREL.END_DT, CONTACTREL.TO_CONT_ID, CONTACTREL.FROM_CONT_ID, CONTACTREL.LAST_UPDATE_DT, CONTACTREL.LAST_UPDATE_USER, CONTACTREL.LAST_UPDATE_TX_ID, CONTACTREL.REL_ASSIGN_TP_CD, CONTACT.CONTACT_NAME, CONTACT. LAST_UPDATE_TX_ID, CONTACTREL.END_REASON_TP_CD FROM CONTACTREL, CONTACT WHERE ((CONTACTREL.FROM_CONT_ID = ? AND CONTACT.CONT_ID = CONTACTREL.TO_CONT_ID AND (CONTACTREL.END_DT is null OR CONTACTREL.END_DT > ?))) UNION (SELECT CONTACTREL.CONT_REL_ID, CONTACTREL.REL_TP_CD, CONTACTREL.REL_DESC, CONTACTREL.START_DT, CONTACTREL.END_DT, CONTACTREL. TO_CONT_ID, CONTACTREL.FROM_CONT_ID, CONTACTREL.LAST_UPDATE_DT, CONTACTREL.LAST_UPDATE_USER, CONTACTREL.LAST_UPDATE_TX_ID, CONTACTREL.REL_ASSIGN_TP_CD, CONTACT.CONTACT_NAME, CONTACT. LAST_UPDATE_TX_ID, CONTACTREL.END_REASON_TP_CD FROM CONTACTREL, CONTACT WHERE (CONTACTREL.TO_CONT_ID = ? AND CONTACT.CONT_ID = CONTACTREL.FROM_CONT_ID AND (CONTACTREL.END_DT is null OR CONTACTREL.END_DT > ?)))"; |
此外,修改 CustomPartyRelationshipExtBObjQuery 类中的 provideSQLStatement() 函数来返回这个新的 SQL
语句,如清单 3 所示。
我们在选择查询名称时要仔细。要找到查询的正确名称,可以访问 MDM API 文档并查找适当的 BObjQuery 类。在我们的样例场景中,我们使用的是 PartyRelationshipBObjQuery 类并选择 PARTY_RELATIONSHIP_ACTIVE_QUERY。
清单 3. 从
provideSQLStatement 函数返回修改后的 SQL 语句
@Override
protected String provideSQLStatement() throws BObjQueryException
{
if (queryName.equals(PARTY_RELATIONSHIPS_ACTIVE_QUERY)) {
return CUSTOM_PARTY_RELATIONSHIPS_ACTIVE_QUERY;
}
else
{
return super.provideSQLStatement();
}
}
|
3. 扩展 BObjQueryFactory 实现类
对于这个样例场景,我们需要扩展 party query factory
类来获得所扩展的 BObjQuery 类。由于我们定制的是 party relationship query,所以这个类将是
PartyModuleBObjQueryFactoryImpl。它具有为 PartyModule 下的每个业务对象创建 BObjQuery 实例的方法。
对于我们的场景,我们可以按如下所示定义这个类。
清单 4. 扩展
PartyModuleBObjQueryFactoryImpl 类
public class CustomPartyModuleBObjQueryFactoryImpl extends
PartyModuleBObjQueryFactoryImpl {
public CustomPartyModuleBObjQueryFactoryImpl() {
super();
}
public BObjQuery createPartyRelationshipBObjQuery
(String queryName, DWLControl dwlControl)
{
if ((queryName == null) || (queryName.trim().equals("")))
throw new IllegalArgumentException("Query Name cannot be empty or null.");
return new CustomPartyRelationshipExtBObjQuery(queryName, dwlControl);
}
}
|
4. 注册这个新的 factory 实现类
注册这个新 BObjQueryFactory 类是很重要的。这种配置允许我们让 MDM Server 知道要执行哪个类,所以创建的是 CustomPartyRelationshipExtBObjQuery 的一个实例,而不是开箱即用的 BObjQuery 类。
为了执行这个配置,修改 TCRM.properties 文件来更改此 Party.BObjQueryFactory 配置。如下所示,提供这个新创建的类(而不是默认的 factory 类)的名称。
清单 5. 更新 TCRM.properties 文件以便
BObjQueryFactory 实现被更改到新类Party.BObjQueryFactory= com.hnb.tcrm.coreParty.bobj.query.CustomPartyModuleBObjQueryFactoryImpl |
上述步骤执行完毕后,就可以将所做的代码更改发布到运行着 MDM 的应用服务器了。为了确保我们执行的属性文件更改能够生效,需要重新启动服务器。
现在通过运行
getPartyRelationship 服务可以测试此服务。
InfoSphere MDM Server 提供了在搜索和查询事务中使用查询级别的选项。这些查询级别让用户得以选择从 MDM 返回对象的细节级别。比如,在运行一个 getPerson 服务时,就可以提供一个 0 到 4 级的查询级别。这个查询级别就控制了为人员方所能返回额外细节信息的各种类型。查询级别越高,我们能获得的信息就越多。
除了使用开箱即用的默认查询级别外,用户还可选择配置定制查询级别来获取新的对象组合。Party 和 contract 域均支持这一点,下列是一些支持子对象选择性检索的服务。有关这些服务所支持的查询级别的更多细节,请参考 MDM Transaction Reference Guide。
getPartygetPersongetOrganizationgetContractgetProductInstance
MDM Server V9.0.x 中引入的可插入 SQL(即 Optimized Transparent SQL,OTS)可帮助减少粗粒度查询事务的响应时间,因而能获得性能上的改善。图 1 展示了可插入 SQL 特性的使用。
图 1. 使用可插入 SQL 特性
以 getPerson 查询服务为例,当此服务执行时,检索 PersonBObj 的每个子对象要调用多个数据库。如果使用的是更高的查询级别,就会有更多的数据库交互,因为这个事务必须要获取 AddressBObj、PersonNameBObj、ContactMethodBObj、PartyIdentificationBObj、PartyPrivPrefBObj 等。
开启了 OTS 特性后,只需对此数据库进行一次调用,因为只有一个 SQL 要执行。
用户可以在如下两种情况使用可插入 SQL 语句:
- 为了用更适合此环境的 SQL 增强现有的粗粒度服务
- 为定制查询级别创建优化的可插入 SQL 语句
要开启可插入 SQL 特性,可以将 tcrm_extension.properties 中的标志 optimized.sql 设为 true,如清单 6 所示。这是一个全局设置并可应用于所有的域和查询级别。
清单 6. 在 tcrm_extension.properties 中开启 OTS
optimized.sql=true |
要增强现有的查询服务,用户可以激活对应于该服务所属那个域的相应 INQLVLQUERY 表中的条目。例如,getPerson 属于
INQLVL
表中的 group_name = 'Person'。要用查询级别 4 来增强这个事务,可以运行如下的 SQL 语句。
清单 7. 调优现有的粗粒度查询服务
update INQLVLQUERY
set END_DT = null
where INQLVL_ID
in (select INQLVL_ID
from INQLVL
where INQ_LVL = 4
and GROUP_NAME = 'Person')
|
用户也可以使用 addInqLevelQuery 和 updateInqLevelQuery admin 服务添加新的定制查询级别:
- 创建一个级别类型 500 的定制查询级别。
- 使用
addInqLevelQuery服务为这个新的查询级别 500 创建一个可插入的 SQL。 - 调优生成的 SQL 语句并使用
updateInqLevelQueryadmin 服务来持久化所优化的这个 SQL 语句。
可插入 SQL 可增强粗粒度的查询服务并同时保持 MDM Server 的现有功能。它们有助于避免多个数据库调用且只通用一个优化的 SQL 调用就能增强查询服务。有了 OTS,数据库管理员就可以基于 MDM Server 实现中的数据模型查看、分析和调优这个 SQL 语句,帮助减少了响应时间并提高了吞吐量。
InfoSphere MDM Server 是物理的主数据存储库,可管理多个数据域,并可被实现来满足广泛的业务需求。相应地,每个 MDM 实现都与其他的实现不同,为实现客户的性能需求,需要在 MDM 数据模型的使用方式以及服务的配置方式上非常慎重。
本文讨论了可插入业务对象查询实现和 MDM Server 所使用的可插入 SQL 框架。所讨论的示例提供了有关此特性的很好的实用知识并涵盖了所要遵循的一些最佳实践。
除此之外,如下的建议对于您将其特性与 MDM 设计并行使用非常有帮助。这些提示可帮助您高效使用这些定制,而又不会损害核心的 MDM 功能:
- 我们常常会引入新的查询级别来支持对 MDM Server 所做的特定查询请求。推荐我们使用自 100 开始的定制查询级别,并谨记产品的可升级性。
- 在仔细验证、分析和调优您计划在 OTS 期间使用的 SQL 语句时,请接受数据库管理员的帮助。这个特性的提供就是为了增强查询服务的性能的。SQL 错误将会导致产品性能的降低。
- 在可插入业务对象查询实现期间,识别核心的业务对象查询实现十分关键。MDM Developers Guide 对如何正确识别要修改的类提供了很好的文档说明。请参见 “Pluggable Business Object Queries” 获取更多相关详细信息。
- 开箱即用的查询名称遵循的是 MDM Developers Guide 中描述的标准命名约定。比如,
PARTY_RELATIONSHIPS_ACTIVE_QUERY是getPartyRelationship服务用来获取双方之间所有活动关系的查询的名称。若要覆盖它来提供您自己的定制查询时,可以将它命名为CUSTOM_PARTY_RELATIONSHIPS_ACTIVE_QUERY,如我们的样例场景所示。 - MDM API 文档提供了有关开箱即用的
BObjQuery类以及这些类所使用的查询参数的有用信息。由于您覆盖的是这些参数中的一个,所以最好对 API 文档比较熟悉。同时,参考 MDM Developers Guide 获得查询参数命名使用的标准命名约定。
IBM InfoSphere Master Data Management Server 能够让公司管理和维护主数据的完整的、正确的视图,帮助公司获得对其主数据条目的控制。InfoSphere MDM Server 通过集中化多个数据域并提供一系列用来支持全部主数据管理功能的预置业务服务,让公司可以从主数据获得最大价值。
由于 MDM Server 自身高度灵活,提供了范围宽泛的定制功能,可帮助您开发满足客户需求的服务。正是因为它具有高度可定制的特性,所以您更需要理解每一层对产品整体功能的影响。本文提供了一些实用信息,可帮助您理解 InfoSphere MDM Server,以及您能以何种方式修改它来满足客户的性能目标和业务需求。它还提供了有关使用可插入业务对象查询和可插入 SQL 框架来定制 MDM 的有用信息,这些信息可在实际的客户实现中使用。
首先要感谢 InfoSphere MDM 产品经理 Henk Albals 对本文创作做出的反馈和贡献。我还想对诸多撰写过类似的、有关 InfoSphere MDM Server 最佳实践的文章的 developerWorks 撰稿人致以诚挚的谢意。在本文的创作期间,我使用了这些内容作为参考,还使用这些内容为几个客户高效实现了 InfoSphere MDM Server。
学习
- 在 InfoSphere Master Data Management Server 信息中心 了解更多相关信息。
- 查阅作为样例场景的这个 Technote:“Severe
degradation of SQL performance with complicated "OR" clauses
on DB2 z/OS platforms”。
- 要阅读有关此主题的更多信息,请参考这本书 Enterprise Master Data Management: An SOA Approach to Managing Core
Information(IBM Press,2008 年)。
- 阅读有关 InfoSphere 最佳实践 的更多信息。
- 在 developerWorks 中国网站 Information Management 专区 了解关于信息管理的更多信息,获取技术文档、how-to 文章、培训、下载、产品信息以及其他资源。
- 随时关注
developerWorks 技术活动 和 网络广播。
-
在 Twitter 上关注 developerWorks。
获得产品和技术
- 用可直接从 developerWorks 下载的
IBM 产品评估试用版软件 构建您的下一个开发项目。
讨论
- 参与论坛讨论。
- 参与
developerWorks 博客 并加入 developerWorks 中文社区,developerWorks 社区是一个面向全球 IT 专业人员,可以提供博客、书签、wiki、群组、联系、共享和协作等社区功能的专业社交网络社区。

Prashanta Chandramohan 是一名经 IT 认证的专家,在 IBM MDM 产品套件上有丰富的工作经验。他目前是 India Lab Services and Solutions 团队的一名高级技术专家,主要致力于 InfoSphere Master Data Management Server 和 Initiate Master Data Service。在此职位上,他已经成功完成了几个跨不同地理区域的 MDM Server 实现,并获得了全球 MDM 社区和客户的广泛认可。他目前与许多北美的客户一同工作,帮助他们在其 MDM 项目中利用 MDM Server 和 Initiate Master Data Service。他还撰写了一些博客,写过有关 IBM MDM、数据监管以及数据质量的一些文章。