zoukankan      html  css  js  c++  java
  • H公司数据同步的总结

    客户的原始需求

    收到H公司的需求信息:他们现在有三个系统:HR系统、OA系统、一卡通系统,各个系统的主要优势如下:

    • HR:有强大的组织架构和人事信息的管理
    • OA:有优秀的流程支持,可以让数据根据既定规则在不同的人员之间流转处理,或做数据自动处理
    • 一卡通:有良好的工卡、饭卡统一管理,充值管理,考勤管理等的功能

     

    此三个系统需要做数据同步,同步需求如下:

    • HR跟OA:OA从HR单向获取组织架构、人事数据,当HR有数据变更,OA把变更数据拿过来,更新OA的相应数据
    • HR跟一卡通:如上,类似HR跟OA
    • OA跟一卡通:OA上有请假、加班、出差的审批流程,审批通过的请假、加班、出差数据写入一卡通。一卡通结合从OA获取的请假、加班、出差数据,以及自身功能采集的打卡数据,进行考勤计算。对于异常的数据送到OA,在OA走考勤异常申请流程,审批完毕后(通过或不通过),把结果写回一卡通。

     

    下图是同步的数据流图,箭头方向是数据流的方向。我方是OA厂商,橙色部分所示。

     

     

        H公司的要求是用Web Service方式同步,一个月内上线,各厂商先给出同步方案。

     

    需求调研

    第一次调研

    按约定时间三方厂商赶到客户现场,到场人员角色如下

    • H公司:项目总负责人、技术人员、其他人员
    • OA:1位实施工程师,1位开发工程师
    • HR:1位实施工程师
    • 一卡通:1位开发(兼实施)工程师

     

    三方系统结构

    • HR:Java + SQL Server 2000 + Tomcat,BS/CS双结构
    • OA:ASP.Net + SQL Server 2005 + IIS,BS结构
    • 一卡通:C# + SQL Server 2005,CS结构

     

    根据各系统的结构,OA跟一卡通用数据库同步,不建议用Web Service 方式;OA跟HR可用用数据库或者Web Service方式。我们各厂商都希望完全用数据库方式同步,可以省事。

    对比各方的数据表。确认各方必须的字段,以保证系统能正常运行。确认同步所需要的业务字段,这是客户的需要。

    我方跟一卡通公司的同步相对简单,双方都有开发人员在,经过两三个小时的讨论与确认,双方的接口以及同步模型基本敲定。

    HR公司来的是实施人员,对系统的底层结构不甚了解,很多问题不能深入讨论。HR系统的技术文档里有相关的Web Service接口介绍,但是限于对HR系统自身数据的增删改查。现在H公司数百个部门、数万个人员,不可能每次同步都把所有部门、所有人员的数据全给OA,再对比哪些数据有变更,然后处理,这样性能太差了。如果要他们提供差异数据,他们的接口必须要重新开发。

    此次调研我方给出的同步方式是:OA跟一卡通用数据库同步。OA跟HR若用数据库同步可以在一个月内上线,如果用Web Service方式,则需要两个月。

    客户最终接受的同步方式是OA跟一卡通用数据库同步,OA跟HR、一卡通跟HR都用Web Service 的方式,可以接受推迟一个月上线。

     

    后来,H公司转发来HR公司的一份同步方案。同步原理是:HR把差异数据放到数据库的中间表,定时扫描中间表,发现有差异数据,就发送HR的数据库链接方式给外部系统(OA ),外部系统(OA)直接读取HR的数据库中间表。

    我看了之后,心里面暗笑,这样的方式,Web Service的同步只是一个幌子,实际还是数据库的同步。但考虑到用户的紧急性,技术我放行了,"只要能尽快上线,功能与时间第一,其它次之"。

     

    第二次调研

    一卡通公司在上海,其他各方都在广州,这时一卡通的开发人员已经回上海。此次调研的出席人员如下:

    • H公司:项目总负责人、技术人员、其他人员
    • HR:1位技术顾问、1位开发人员
    • OA:1位开发工程师

     

    HR公司的两位人员明显事前没做什么准备,没有一个完整的同步模型。我带着事前准备的同步方案,这样我显得比较主动。我的同步模型是:首先做手工同步,OA已经被H公司应用多年,数据肯定不能够清空,然后从HR系统来拿全新的数据。这样我要做中间表,存放HR系统与OA系统的主键对应关系,手工同步的作用就是填充双方系统的既有对应关系。其次是差异同步,HR新增数据,OA也跟着新增数据,并在OA中间表插入对应关系;若HR修改数据,OA从中间表找到相应记录,更改之;若HR删除数据,OA从中间表找到相应记录,只做记录,但不删除。

     

    系统相关结构如下:

    • OA的部门与机构分开在两张表,HR的部门与机构在同一张表,用不同的状态区别。
    • HR有三个完全独立的数据库,每个数据库有自己的机构、部门、人员。三套机构、部门略有差异,大部分数据是冗余的;而H公司的人员分布在三个数据库中。

     

    此次调研确定了:

    • HR通知OA有数据变更的格式,包含OA连接HR数据库的格式;
    • HR中间表的名称、表列及数据格式;
    • OA接收HR通知的接口;
    • OA返回同步结果给HR的格式;
    • OA按严格的时间顺序 模拟HRP的数据变化来更新OA的数据,组织、人员、人员兼任部门职位信息,HRP给我们的必须是按更新时间排序的,OA用归并算法来同步这些数据;
    • 数据约束:HR的某些部门不传给OA;HR目前有两个部门,"总部"与"分部",二者在HR是并列的机构,但在OA中只有一个机构"总部","分部"降了一级,作为总部的一个子部门;
    • 若OA同步过程出现错误,则停止同步,避免同步的错误越来越大;
    • 同步模型就上图的方式。

     

    从我的主动与HR的被动,我想:到客户现场务必要事先做好准备,否则丢失的是客户对自己能力的信任和对公司能力的信任。事前我曾花了近三天时间写了同步方案,有些是实用的,有些是华而不实的,不实用的东西尽量不写,否则只是徒劳,而有用的东西尽量详实。

     

    流水帐差异还是全表差异

    流水帐差异 是指主表与中间表是一对多的关系,每发生一次数据变更,就往中间表写入一条数据,中间表的数据行多于主表的数据行,例如组织表organization的部门"人力资源部"的ID为11,则11这条记录会在中间表出现多次,出现一次代表"人力资源部"的一次数据变更。

        全表差异 指主表与中间表是一对一关系,每发生一次数据变更,就覆盖中间表的对应数据。

        HR提供的方案是组织、人员中间表都用全表差异的方式。我第一印象是不妥,可能会导致我们OA数据混乱,我一时举不出反例,但是潜意识里认为这样的数据不安全。冥思苦想很久,如果HR在10点新增了部门A,11点在A下增加了部门subA,12点修改部门A的名字为AA,这个12点覆盖了之前的10点。此时,OA从HR同步数据,发现11点增加了部门subA,但是找不到它的父部门,因为HR标识其父部门在12点新增(修改)。

        所以,组织只能用流水帐差异的方式。HR的开发人员似乎特钟情与全表差异的方式,人员中间表还希望用这种方式。但是,他们的人员没有主键,只能用工号充当,而工号又后变更,全表差异也给推翻了,还得用流水帐差异的方式。

     

    别人提供的技术方案未必是正确的,可能是误导,甚至错误的。还需自己进行技术论证。这个同步项目本身的确存在较多这种似是而非的陷阱,需要格外小心,稍不慎则犯错。

    第三次调研

    经过之前的调研,OA跟HR的同步正风风火火地开发,大概是此同步项目启动后的一个月,一卡通的开发人员才来到广州。

    OA跟一卡通的同步方案跟第一次调研的一致,本次调研确认每个接口的签名,主要体现是存储过程与视图,包括存储过程的名称、参数的名称及参数类型,视图的名称、其列名称、列类型。

    HR系统的人员不能提供唯一键,唯一可做标识的是工号,然而工号又可能会变更,还好H公司的工号不会重复利用,否则数据就可能混乱。

    由于工号勉强做唯一标志,而工号又会变更,我抛出了一个问题:HR改工号后,若OA从HR同步成新工号,而一卡通未同步成功还是旧工号。此时OA与一卡通同步,就会找不到人员匹配。H公司决定:OA先从HR同步数据,OA同步成功后,一卡通才从HR同步数据。OA向一卡通发数据时需发新工号与旧工号,若一卡通匹配不了新工号就匹配旧工号;一卡通向OA发数据时,只发一个工号,OA用新工号与旧工号匹配之。

     

    现在回想,人员似乎可以补用GUID来唯一标识之。

     

    HR、OA、一卡通三个厂商之间互相讨论,到方案敲定,时间已是晚上六点。各有一份自己与其他两个厂商的同步方案文档,各写各的。H公司要求我们三方把三份文档整合成一份,由于一卡通的开发人员第二天要赶回上海的公司,整合文档一定要在当天出来。文档整合使用"Ctrl-C" "Ctrl-V"很容易,麻烦的是文档的排版,折磨到将近十点才完毕,更名为《H公司三方系统同步方案》。

     

    开发与测试

    经过第二次调研后,OA跟HR的同步开发工作就紧锣密鼓地进行。我跟HR的开发人员一个星期几乎有两三天在H公司上班。H公司也很重视此项目,专门分配了两个人员来协助我们,搭了三套虚拟机,各安装一个厂商的程序,模拟他们的现实环境。

     

    HR公司的艰难

    HR系统只能用一个"怪异"来形容:

    • 数据库不能用SQL Server的备份还原功能来加载到虚拟机,而要用程序来恢复,数据库上10G,程序创建一次数据库将近1小时,然后报错,如是折腾了三天都失败,最后好像是从正式环境下复制数据库文件到虚拟机的相应目录,数据库的部署才成功。
    • 数据散布在三个数据库中,同样是人力资源部,在库1的编号是0105,在库2的编号可能是0106,在库3中可能是0207。OA只与HR的库1对应,若同属于人力资源部的杨过与郭靖,库1中杨过的部门编码是0105是正确的,库2中郭靖的部门编码给OA的不应当是0106,而应该是0105,否则会造成OA数据混乱。我想光是将数据整合成一致的对外接口都够他们受了,并且维护也不是简单的事情,这不是我方的任务,管他的。
    • 所有表都没有主键。组织表organization 的唯一标识是组织编码,但是部门(组织)移动后这个编码是会变更的。我建议HR在组织表新增一个自增列,来创建唯一ID。人员散布在三个库中,无法用自增列,因为自增列在不同的库中会重复,只有将就着用工号。
    • HR公司是个代理商,开发人员没有HR系统的源代码,只能在系统外围做处理

     

    开发初期,接口频繁变动,一个月后,接口基本稳定,HR与OA同步的某些模块已经初步实现。此时一卡通公司开始参与进来,经过上面的"第三次调研",一卡通的开发人员把电子文档发回公司。第二天一大早我接到H公司项目负责人Z的电话,问我实现方案是否怎么变了,何时变了。我告诉她在第一次调研后HR发来的文档就已经变了。接着我收到H公司转发来的一卡通的Email。Email内容痛陈HR与OA的同步方案是非数据库非Web Service 同步的四不象,复杂有加,实用不足,逻辑存缺陷,安全有隐患,并提供了他们的同步方案,请H公司重新做技术审核云云。洋洋洒洒两三千字,图文并茂,措辞犀利,我打从心底里面佩服作者的文笔功力。

    文章不是专门针对我的,我没有太大歉意,但是我没有特意指出这个问题给H公司,我有连带责任。我原先是希望尽早实现功能,让客户尽早上线。如此看来,我的算盘打错了,欲速则不达,现在推翻之前的工作重来,项目进展更慢了。

    我反思:客户不是傻子,不要忽悠客户,到头来只是忽悠自己。我同时也纳闷,早在H公司转发HR公司邮件的时候,他们也收到邮件,怎么当时不指出此问题的严重性,而留待至今。

    OA接口的开发

     

    HR的同步方案被一卡通推翻后,H公司跟HR公司重新确认了同步方案,如上图所示。我花了5个工作日来重新实现被推翻的功能。同时我重构了程序,原先很多工作都放在程序上做,程序写得很长,后来我又把大部分工作挪到数据库级别来做,数据库密集的工作,应该让数据库来直接处理。程序变短了,逻辑更清晰:

    • 调用HR的Web Service接口获取差异数据XML,
    • 把XML转换成DataTable,
    • 迭代DataTable来做同步操作
    • 把同步结果返回给HR系统

       

    然而存储过程变长了:

    • 根据HR发来的数据,检索对应的OA数据
    • 数据容错校验
    • 若容错校验通过,同步数据到OA

     

    这样的结果是,程序的责任减轻,只是做了数据获取与数据传递(到数据库)和记录日志的作用,很容易保证程序的正确。而存储过程的责任加重,问题的出现也基本在此。存储过程写得够长的,我出来,逻辑结构也很清晰,该注释的也注释了,人员的同步与兼任部门职位的同步也容易调试。但是组织的同步一直折磨着我,特别是HR系统中"总部"与"分部"是并列关系,在OA变为机构与子部门之间的父子关系,我翻来覆去改动了多次,依然无法保证数据的正确对应关系。SQL脚本的不易调试,如何验证我的存储过程是正确的,或者说如何证明我的存储过程是错误的。最后我写存储过程来测试存储过程,这也不失是一种很好的单元测试方法。

     

    OA跟一卡通的开发工作大概用了3个工作日便完成,运用链接服务器从OA数据库链接到一卡通的数据,调用它们的存储过程和视图。唯一困扰的是在Sql ServerManagement Studio中直接远程调用一卡通的数据库对象时很顺利,但是放在作业中让Sql Agent自动调度时出现诸如"安全上下文"的错误,折腾了两天没解决,在公司经理的指导下,配置一个Windows帐号来启用Sql Agent服务后,并给该帐号Sql Server的相应权限,问题得以解决。

    部署

    客户的机房里面运行着重要的程序、存放着重要的数据,稍不小心就有可能把程序搞垮,或把数据弄坏,尽管客户事前已经做过备份,一旦出现不可回退的误操作,还原现场也需要耗费大量的时间。所以,一个好的部署方案应该有序、不出差错,这需要事前充足的准备,列一个清晰的部署计划列表,第一步做什么、第二部做什么,井然有序。先把此部署列表给客户,好让他们清楚整个部署过程,消除心中疑虑,知道部署人员在干什么,将要干什么,这样客户会更好地支持部署人员的工作。这些我们都基本做到了。

    结语

    如何对待不合理需求

    H公司最初给的上线时间要求是一个月,当时李经理指导我把此同步项目当作正常的二次开发项目对待, 调研、需求分析、详细设计、代码开发、测试、试运行、部署,但是这样的项目周期远超过客户的时间要求一个月,我自身也疑惑,到底以哪个时间为参考;后来一卡通也提到,延迟上线造成的不便可以通过其它途径来弥补。客户的要求的时间限定只是一个参考,否则软件不能交付、或者交付了有严重问题的软件,你客户敢用吗?客户的时间需求也是一项需求(应该算非功能性需求吧),当需求不合理时,尝试说服客户,否则后果还是客户自己承受。

    文档的规范

    H公司和一卡通的文档很规范,尤其是一卡通,常常图文并茂,图形很漂亮。

    工作范围

    接口是静态的,怎么处理接口是动态的,OA跟一卡通双方技术讨论的时候,都只提接口的事,没有任一方提出谁来处理这接口,谁来创建SQL Server作业调度对方接口。而我的心态是我来做,毕竟做过了就是经验,对我自己或对公司都是一种经验,以后可以借鉴。

     

    • The end
  • 相关阅读:
    jQuery -JQ方法大全
    Javascript模块化编程:模块的写法
    angular 路由的简单使用
    jQuery Validate验证框架
    网站出现403 Forbidden错误的原因和解决办法
    js下拉刷新
    bootstrap栅格系统的属性及使用
    AJAX 跨域请求
    用js实现分页效果
    用一个例子读懂 RequireJS
  • 原文地址:https://www.cnblogs.com/feixian49/p/2181795.html
Copyright © 2011-2022 走看看