Edeity's Blog

产品回顾:单据,及数据一致性

单据,各行各业用来记录在经济业务过程或结果的一种凭证

NC的单据,在展示方式通常包含列表态卡片态

基于列表态和卡片态可以衍生多个数据副本

数据的表现形式一般为:表头表体表尾;一般地,表头记录通用数据,表体记录差异数据,表尾记录操作动作等相关信息等;

不考虑业务逻辑,则可简单认为,单据就是对一个业务流中涉及的多个数据库表的增删改查的一种组织形式

单据:调整凭证制单
在上图基本单据的实现过程中,遇到了两点挑战:
  1. 前端,列表态,卡片态表头表体以及衍生多个数据副本之间的数据转换
  2. 前端展示与后台数据的一致性

在此仅记录在保证一致性的一些实用技巧(前端角度,后台同学勿取笑)

一次性提交

要点有二:

  1. 只提交发生改变的数据:减轻网络层及服务端压力,基本技巧,略过;

  2. 一次性提交

    原考虑不周,表头和表体是分开提交的;然而表头表体保存时,既有基本属性校验,也有业务逻辑计算,后台时有抛错,导致表头保存成功后表体不成功(表体是在表头保存成功后回调保存);假若一次提交,则能利用数据库,进行事务级的回滚

    另一点,就是初步定需求时,表头表体仅以表头主键关联,后续在执行规则(某种业务逻辑)时,才发现需根据单据所有表体计算合并范围(保存到表头),假如分开提交,则需在表体成功后进行回写操作,这种影响数据流单向流动的操作,一般是不鼓励的。一次性提交能降低某些隐性需求浮现时对代码层的影响。

    当然,若能屏蔽数据库的表,在前台仅以统一数据结构出现,能大大减低数据流操作以及前后台刷新同步的复杂程度。不幸的是kero.js对数组和对象的MVVM支持仍停留在石器时代,只好作罢;

内存锁

BDPKLockUtil.lockString(pk_vouchhead); // pk_vouchhead,唯一标识

基本原理就是每一单据生成一个唯一标示,并索引是否已存在,若存在,则抛错,否则,锁定至事务执行完毕;个人觉得还是一种比较简单优雅的实现。

时间戳

时间戳则是用来保证业务员总应在最新的数据上进行操作。基本原理就是在表内添加TS列,记录每次操作的时间。假如提交的数据中,最后修改的时间和当前数据库存储的时间不一致,则可认为版本过旧或版本错误;也能从侧面防止假数据的录入。