您的位置:首页 > 数据库 > Mongodb

MongoDB 与关系型数据库(Oracle)关联统计实践方案(续)

2016-04-04 22:13 651 查看
本文基于上篇《MongoDB 与关系型数据库(Oracle)关联统计实践方案 》的设计,采用数据冗余方案,通过增加更新MongoDB中文档状态和时间,来满足查询需求,提高查询开发效率和代码的执行效率。

在系统设计中,已经实现了更新流程实例状态为流程办结状态(系统中定义为“2”),由于初次使用MongoDB,设计中忽略了文档状态的标识。

为此,需要完善系统,以提高系统查询性能,避免不合理的关联查询。其解决方案如下:

利用现有更新流程实例状态的服务“updateStatus”;

避免改动代码,尽量使用现成的服务;

考虑SOA架构影响,减少服务间依赖

减少代码极其Jar包间的依赖。

如下图所示,利用流程配置中,“结束”节点Message Map调用更新流程实例状态的方法。(Cordys流程平台提供的功能)



输入参数为Java方法“updateStatus”:

com.unicom.bopm.workflow.BIZ_INFO_INSTANCE.updateStatus(string(instance:instanceProperties/instance:organization/text()),string(bpm:inputMsg/bpm:inputData/bpm:bizInstanceId/text()),'2')


为了兼容早期设计和流程部署成果,扩展使用源项目代码中方法:“com.unicom.bopm.workflow.BIZ_INFO_INSTANCE.updateStatus”。(此BIZ_INFO_INSTANCE类是关系型数据库的“表”实体对应)

public static boolean updateStatus(String orgDn, String bizInstanceId, String status) {
String[] paramNames = {"bizInstanceId", "status"};
Object[] paramValues = {bizInstanceId, status};
SOAPRequestObject sro = new SOAPRequestObject(orgDn, "http://unicom.com/workflow", "UpdateBizInstStatus", paramNames, paramValues);
sro.execute();
/* 在此处增加更新MongoDB文档状态代码 */
return true;
}


改造此updateStatus方法,引入对MongoDB的操作,设计UML如下:

Created with Raphaël 2.1.0BIZ_INFO_INSTANCEBIZ_INFO_INSTANCEC_MONGODBC_MONGODBBIZ_INFO_INSTANCEBaseBIZ_INFO_INSTANCEBaseOracle数据库Oracle数据库MongoDB数据库MongoDB数据库1.UpdateMongoByInstance2.GetBizInfoInstanceObject2.1.从Biz对象中获取文档ID3.editMongoByJosn4.修改文档数据5.返回服务状态

通过测试“2.调用获取文档关键字服务”GetBizInfoInstanceObject,从返回值中,获取文档集合和_ID。其中,GetBizInfoInstanceObject是类BIZ_INFO_INSTANCEBase成员,在UpdateMongoByInstance服务中,需要通过SOAP服务可以调用使用。



如图所示,我们只需要:”MONGO_BO_ID”和”BIZ_RVSN_NUMBER”两个关键字就可以定位到文档。

这样,新增代码如下:

if (status.equals("2")){
Date newDate = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
//设置文档完成时间
String jsonString = "{'completedtime':'"+dateFormat.format(newDate)+"','status':'2'}";
String[] pNames = {"collection", "instanceid", "jsonStr"};
Object[] pValues = {"ZFSP",bizInstanceId,jsonString};
//调用Webservice,通过业务实例修改文档——UpdateMongoByInstance
SOAPRequestObject sromongodb = new SOAPRequestObject(orgDn, "http://unicom.com/common/attachment", "UpdateMongoByInstance", pNames, pValues);
sromongodb.execute();
}


其中,在C_MONGODB类中,新建服务UpdateMongoByInstance,修改文档的服务代码如下:

// 修改MongoDB的内嵌文档
public static String updateMongoByInstance(String collection,String instanceid,String jsonStr,String oid){
//按文档id修改文档
if(oid != null && !"".equals(oid.trim())){
editMongoByJosn(oid, jsonStr, collection);
return "true";
}
else{
//按业务实例ID修改文档
if(instanceid != null && !"".equals(instanceid.trim())){
String  namespace = "http://unicom.com/workflow";
//取流程实例Webservice
String  methodName = "GetBizInfoInstanceObject";
String[] parasName = {"BIZ_INSTANCEID"};
Object[] parasValue = {instanceid};
SOAPRequestObject bizRequet = new SOAPRequestObject(namespace, methodName, parasName, parasValue);
BusObject bizBus = bizRequet.getObject();
String v_oid = bizBus.getStringProperty("MONGO_BO_ID");
String v_collection = bizBus.getStringProperty("BIZ_RVSN_NUMBER");
editMongoByJosn(v_oid, jsonStr, v_collection);
return "true";
}else{
return "false";
}
}
}
/**
* MongoDB修改的方法
*
* @param oid        主键ID
* @param json       要修改的JSON数据
* @param collection 集合名称
* @return 修改时返回主键ID
*/
public static String editMongoByJosn(String oid, String json, String collection) {

DBCollection coll = MongoDBUtil.getCollection(collection);
BasicDBObject a = new BasicDBObject();
DBObject dbo = (DBObject) JSON.parse(json);
BasicDBObject updateCondetion = new BasicDBObject();
updateCondetion.put("_id", new ObjectId(oid));
String iid = updateCondetion.get("_id").toString();
a.put("$set", dbo);
coll.update(updateCondetion, a);
return iid;
}


遇到的问题:

在实施中,还是出现了服务依赖Jar包的问题。在Cordys服务部署中,service group分配与所开发的服务对应关系不是很理想,例如:

涉及到MongoDB数据库基础服务,都应归集到一个Service Group中,并且不与关系型数据库业务操作服务纠缠;

关于事务也是很头痛的问题,这里Service Group分配不理想的原因,也是基于事务的要求,规避SOA在异步处理时不可控的问题。

参考:

MongoDB 与关系型数据库(Oracle)关联统计实践方案》 肖永威 2016年3月
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mongodb 数据库 SOA cordys