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

本文基于上篇《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.0 BIZ_INFO_INSTANCE BIZ_INFO_INSTANCE C_MONGODB C_MONGODB BIZ_INFO_INSTANCEBase BIZ_INFO_INSTANCEBase Oracle数据库 Oracle数据库 MongoDB数据库 MongoDB数据库 1.UpdateMongoByInstance 2.GetBizInfoInstanceObject 2.1.从Biz对象中获取文档ID 3.editMongoByJosn 4.修改文档数据 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月

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肖永威

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值