开发小技巧系列 - 重复生成订单

开发小技巧系列文章,是本人对过往平台系统的设计开发及踩坑的记录与总结,给初入平台系统开发的开发人员提供参考与帮助。

重复生成数据,在实际的开发过程中是一个常见的问题,“重复生成订单”只是一个例子,从这个例子中,来说明怎么去防止出现这个问题,也给初入开发的人员提供参考。

怎么会出现这种问题呢?

情况1: 用户界面操作

用户在界面上连续点击多次“按钮”,由于网络或者后台处理时长的原因,浏览器对服务器发送多次HTTP请求,导致服务器接收到多次一模一样的数据,在数据库中生成多条一模一样的数据。

情况2: 后台接口对接/MQ消费

在做功能开发的过程,有时候需要跟其他业务系统进行对接,通过http或者MQ或者其他协议方式,来交互数据,由于网络或者其他原因(比如在MQ场景中,没有控制好锁),导致服务方多次执行同一份数据,生成一模一样的数据库记录。

“数据重复被处理”的问题,其实是数据幂等性的问题,可以使用幂等性的机制来解决,保证同一份数据的处理结果只有一个。那有什么解决办法呢?

方案一

前端界面加loading/按钮置灰,即用户操作按钮过后,将操作过的按钮灰,不能连续点击,或者界面加上一个loading的效果,让用户进行等待。这是最普通的处理方式,能防住普通的用户,但是防不了通过接口调用(高级用户)。

方案二

预分配ID,在下单的场景中,可以预先分配一个ID(ID可由后台生成,或者前端生成),后台在处理数据时,对同一个ID,只处理一次,多次提交后台时,返回特殊状态码给前端(表示“操作在进行中,不要重复提交”),可以采用redis的锁来控制“预分配ID”。

方案三

数据表唯一主键法,也是在数据提交前,预分配一个唯一的ID,或者拿业务的ID(如订单号),在消息的场景中,可以使用MQ的messageId。然后在数据库中新建一张表,用来存储收到的数据/消息,将预分配的ID设置为“唯一主键”, 只有当数据写入成功后,在执行业务处理,如果写失败,则返回不处理(重复数据/消息),这个场景在之前做商城时使用过,通过订单的消息来做各个维度的统计(前期未考虑到大量的消息的情况下,没有很好分配好锁的机制)。

这个方式适用于其他数据一致性的场景上,订单重复只是其中之一。

如果读者有更好的方法,可以回复。


开发小技巧系列文章:

1、 开发小技巧系列 - 库存超卖,库存扣成负数?


更多内容,欢迎关注订阅号:技术老男孩

腾讯云推出云产品限时特惠抢购活动:2C2G云服务器7.9元/月起
本文链接:https://www.jhelp.net/p/kt9EFEqQ8AztcO7C (转载请保留)。
关注下面的标签,发现更多相似文章