前言
近期接到开发任务,需要以图书为中心开发一套书籍在线商城系统,由于之前没有做过相关的系统,借此机会梳理总结一下各个模块相关技术。
简易实现,项目开发中,有更好的想法请指教。
订单模块
订单是核心模块之一,相较于前置的购物车模块相对简单。此模块的主要职能是创建正确的订单,包括商品正确性、库存正确性。
商品正确性
商品正确性分为价格正确性
和商品有效性
。
为了保证数据的正确性,用户在结算页面展示的价格,在提交订单时,后端是需要再次计算的,这样就引申出些问题:
- 假设用户提交订单的瞬间,用户修改了某商品的数量(通过其他客户端)。
- 假设用户提交订单的瞬间,系统修改了某商品的价格。
- 假设用户提交订单的瞬间,系统下架了某商品。
以上情况出现时,最终结算时,支付的金额与指点展示的不一致,甚至无法结算(商品全部下架)的情况,针对以上情况做了以下操作:
- 在用户确认提交订单时,前端把之前计算的价格传给后端,与下单逻辑计算出的价格进行比较,俗称比价环节。如果两次计算价格不一致,说明商品、购物车有变动,需要用户再次确认,以防止商品变动用户不知道的情况。
- 为了防止用户的多次提交,这里使用令牌的方式,每次提交订单时,需要调用获取令牌的接口,后端在处理下单逻辑前需要验证令牌的有效性,这样防止用户多次提交。
ps:这里考虑了某些极端情况。
邮费相关
订单的提交逻辑一般流程为:
- 购物车(用户勾选需要结算的商品)
- 订单确认页(罗列出购买商品,初步计算价格,选择地址后计算运费信息)
- 订单提交页(在所有的费用计算完毕后,提价触发订单创建功能)
- 订单创建
邮费是由后端进行计算的,也需要展示给用户,订单确认页是给客户选择地址计算运费并展示功能。
库存正确性
在校验商品时,同步查询库存信息,并对购物车购买的数量进行校验,是否满足此用户的购买,并进行锁库存
。
锁库存
顾名思义:库存表锁定商品的一部分库存。
库存表设计时,描述库存使用两个字段,分别为:库存数、锁定库存。
锁定库存 = 已售 + 已下单数量
库存数 = 锁定库存 + 未售数量
这样做的好处在于,当修改库存时,刚好有人在购买商品扣减库存,若使用单个字段来描述会出现以下情况:
A修改库存流程:①查询库存数 -> ②设置新值 -> ③使用乐观锁的方式更新。
B购买商品流程:①查询库存数 -> ②验证库存数量是否足够 -> ③使用乐观锁的方式更新。
其中,B②先运行,A②再运行,会导致③步同时执行,总会有一步失败,不管哪一方失败,总会带来用户体验或者其他问题。
并发问题
当然这里也存在并发问题,当同一个用户在移动端和PC端同时发起支付,这样会导致创建的单据出现问题,影响系统的正确性,这里也需要添加分布式事务锁,当拿到锁之后才可以继续后续的操作。