订单是电商中重要的一环,我们在面对订单系统的时候,有很多方面需要仔细的考虑
一个合格的订单系统,基本的要求就是数据不能错
一个订单从下单到收货,少不了更新数据的操作,那么我们为了避免状态更新出错,我们需要注意代码方面问题
首先是代码准确无Bug
然后正确使用了数据库的事务,比如一个操作中多个INSERT必须要在一个数据库事务中执行,执行数据库事务的操作,要么一起成功,要么一起失败
首先,我们看下订单系统相关的设计,在此处我们讨论的是最为核心,共通的业务和功能上
订单的整体流程
1.创建订单
2.跟购物流程更新订单
3.查询订单
对于订单的表结构
我们需要有如下的几张表
订单主表 订单表 保存了基本信息
订单商品表 保存商品详情
订单支付表 订单的支付或者退款的详情
订单优惠表 订单使用的优惠信息
上述中,主表和多个子表基本上都是一对多的关系
关联外键就是订单主表的主键,也是订单号
对于第一个问题
重复下单的问题,一个订单系统,必然具有订单接口,或者订单的按钮,用户在浏览器上点击按钮的时候,浏览器就会请求接口,后端就会往数据库中插入一条数据
加入,创建订单的时候,一不小心发了两次怎么办呢?需要我们防止重复发送
所以,后端的系统需要具有幂等性,就是任意调用产生的影响会和上一次执行的影响相同
对于订单服务,如何保证发来的创建订单的请求不是重复请求的呢?
常见的解决方案是,我们给订单系统增加一个生成订单号的能力,这个服务器每次返回一个全新的,全局的订单号,用户进入创建订单的页面的时候,前端页面先调用这个生成服务号得到一个订单号,用户提交订单的时候,带着这个订单号
这个订单可以是唯一键,来进行约束,从而保证了唯一性的约束,只有一次INSERT语句是成功的
其次,是ABA问题
就是关于订单号状态多次修改,可能最后修改会原始状态,导致的ABA问题
常见的解决ABA问题的方式是,利用八本控制,在更新数据的时候,将版本号一同作为更新请求的参数,带给订单更新服务’
UPDATE orders set tracking_number = 666, version = version + 1
WHERE version = 8; |
每次带着版本更新,做到一种MVCC版本控制
这样,就能避免了ABA问题的出现
然后,我们总结一下这节课的内容,就是订单的幂等问题
首先是避免网络 服务器等不可靠因素,避免重试错误
对于创建订单服务器,可以通过预先生成订单号,利用数据库中顶到号唯一约束这个特性,避免重复写入订单,实现创建订单的幂等性
对于更新订单服务,通过一个版本号机制,每次更新数据前校验版本号,更新数据时候更新版本号,解决ABA问题