录单APP项目中的问题

目录

分页重复数据问题

防止订单重复问题

订单号唯一问题

Web端报表系统使用导致APP端使用卡顿



分页重复数据问题


背景:

先解释一下,我们 app 项目中有一个录入订单模块,在这里每个店铺的工作人员会因为客户下单,在当天不停的进行录单;

这些订单按照当天的顺序形成一个单号,例如1,2,3,4… … 就这样;

app 中还有一个功能,就是插单,也就是如果有一张单据昨天忘记录入,那么可以添加插单时间到昨天,那么这张订单就插入了昨天;

但是,录单的工作人员有几个人,也就是同时有人会刷新这个页面,看到订单列表;

因为 app 是下拉刷新,加载第二页数据,并且是按照单据倒叙排列的,最先出现的是最新的单据;

这时候员工A如果开单到 25 号单据,然后再开第26的时候,员工B想要刷新第二页(按照每10张一页),那么本来应该看到的是15号单开始的第二页,

由于员工A完成26号单,这时候刷出来的是16号单开始的第二页,也就是25,24,23,…,16,16,15,14,…中间重单了;


解决方法:

为了防止这种现象,必须在后台增加一个 过滤条件

因为由时间排序,那么只要拿创建时间 created_at 与 前端传来查询时间 search_at 进行比较就可以筛选出第二页;

由于还有插单,所以插单的时间绝对不能覆盖创建时间 created_at,要有一个插单时间 inserted_at,这样排序用 inserted_at 来排序即可;



防止订单重复问题


背景:

由于这是一个给批发市场店铺的 app ;所以批发市场的店铺人员有限,但每天的订单数量又比较多,

这时候员工录入订单往往快速而又烦躁,对订单开单后可能会不停点击提交;虽然 IOS 端和 Android 端以对点击按钮做了屏蔽;

但是还是无法百分百杜绝一个单重复性提交;

这时候需要前端和后端配合一起防止同一张订单重复问题;


解决方法:

前端给订单生成一个唯一码,一般用时间戳+随机数生成,这里我们用单词 exist_flag 代替;

然后前端发出请求,带上这个参数到后端;

后端接收到请求后首先将其用 redis 进行检验判断是否重复;

1
2
3
4
5
if (Redis::get('orders:'. $user_id . '-' . $exist_flag)) {
    return $this->fail(self::ERROR_CODE, "你还有订单正在进行中,请勿重复提交");
} else {
    Redis::set('orders:'. $user_id . '-' . $exist_flag, 1, 180);
}


订单号唯一问题


背景:

正如前面所提到的,订单按照每日生成唯一的订单号1,2,3,4,5 ……;

这是针对当天唯一的号码,并且当天不能重复,并且生成单据最好能较快,不要因为顺序问题影响体验;


解决方法:

利用联合唯一索引来解决;

例如单号字段为 transaction_daily_serial, 时间为 inserted_at

这里使用插单是插入选择日期的最后单据,因为这样不会导致重新更改其他单号;

那么联合唯一索引:

1
alter table transaction add unique index daily_sel_ins_at(transaction_daily_serial, inserted_at);


Web端报表系统使用导致APP端使用卡顿


背景:

APP 作为一个有点类似 ERP 的在线客户端,客户需要一些导出的Excel报表数据,包括(出入库数据,货品数据,订单总览)等等内容;

但由于数据内容非常庞大,并且客户不想要分批下载,他要一张excel展示所有时间段的数据;一开始数据量不多的时候,系统也没有为他们加时间限制;

后期,数据库数据量已经达到10G以上的时候,一段时间在业务高峰期出现 app 使用卡顿现象;

通过查询后台日志,我发现在这些卡顿时间都出现报表导出接口;

并且 APP 和 web 报表系统 是放在同一台服务器上;


解决方法:

预想方案是有以下几个:

  1. 分库【主从数据库】:因为 web 报表系统是查询数据,导出数据的系统,所以是只读系统,而 APP 是可读可写的; 分库可以保证 web 报表操作不影响 APP 手机端;

  2. 数据归档:将旧数据进行归档存储;

  3. 解决慢查询SQL

  4. 限制导出数据大小


由于公司项目较多,经费有限,无法再提供多一台服务器来专门用作 web 报表系统,所以方案一被取消;

数据归档虽然 CTO 答应采纳,但是当务之急是先解决目前问题,所以先从 方案三 和 方案四 下手;

方案三:通过阿里云的慢查询日志,定位到 SQL 语句,从而定位代码段;大部分慢查询可以通过添加联合索引解决; 但是一部分 smelly 的 SQL ORM 旧代码,就得重新编写优化;

方案四:根据客户需求和对应一个月的单据数量,给出最多只能下载一个月的数据;



Comments