再谈购物车 - 逻辑细节处理

前言

购物车作为整个电商系统中核心的业务逻辑,本文对于其中的一些操作细节处理做了详细的梳理(仅代表本人遇到的业务场景),对于特殊场景的细节处理在文章末尾做了讲解。

文章中商品默认为电子商品,不考虑库存

购物车

查询购物车

  • 获取购物车缓存数据
  • 判断是否需要更新购物车
    • 每人购物车都配备一个时间字段
    • 系统商品存在一个最后操作时间标识
    • 比较时间确认是否为最新版商品信息
  • 校验所有商品的状态
    • 上下架、权限、版权
    • 判断价格,使用加密价格进行校验
  • 更新缓存并返回数据

加入购物车

  • sm2加密传参、校验参数
  • 校验防重令牌,防止重复提交
  • 获取购物车数据(redis hash存储商品信息)
  • 校验并更新
    • 获取分布式事务锁
    • 是否超过购物车商品种类数量上限
    • 是否存在于购物车、已购买过
    • 商品正确性(是否存在、版权、上下架、阅读权限)
    • 使用最新商品数据更新购物车、并更新标识
    • 释放锁
  • 返回数据

批量添加到购物车

  • sm2加密传参、校验参数
  • 校验防重令牌,防止重复提交
  • 校验商品列表有无重复
  • 获取购物车数据(redis hash存储商品信息)
  • 校验并更新
    • 获取分布式事务锁
    • 是否超过购物车商品种类数量上限
    • 分批次校验商品是否已经购买
    • 过滤出未添加的商品进行添加
    • 商品正确性(是否存在、版权、上下架、阅读权限)
    • 使用最新商品数据更新购物车
    • 释放锁
  • 返回数据

结算

去结算

  • sm2加密传参、校验参数
  • 校验防重令牌,防止重复提交
  • 购物车过滤出待确认的商品,并校验商品数量是否来自于购物车
  • 计算价格
    • 优惠、运费等
  • 返回数据
    • 商品信息
    • 总价
    • 令牌,用于提交订单使用

直接购买去结算

  • sm2加密传参、校验参数
  • 校验防重令牌,防止重复提交
  • 分批次查询商品,校验商品正确性
  • 计算价格
    • 优惠、运费等
  • 返回数据
    • 商品信息
    • 总价
    • 令牌,用于提交订单使用

订单

提交订单

  • sm2加密传参、校验参数
  • 校验防重令牌,防止重复提交
    • 防重令牌来自于去结算或直接购买
  • 校验用户权限是否支持此次购买
  • 校验发票等信息填写
  • 校验商品是否已经购买过
  • 创建订单
    • 获取分布式锁
    • 获取最新商品数据,验证商品正确性(是否存在、版权、上下架、阅读权限)
    • 计算价格,校验价格是否变动
    • 构建订单数据、订单商品数据
    • 保存订单相关数据,发送订单信息到延时队列
    • 释放锁
  • 返回提交订单的令牌,并存入缓存,过期时间与订单一致

直接购买

  • sm2加密传参、校验参数
  • 校验防重令牌,防止重复提交
    • 防重令牌来自于去结算或直接购买
  • 校验用户权限是否支持此次购买
  • 校验发票等信息填写
  • 校验商品是否已经购买过
  • 获取最新商品数据,验证商品正确性(是否存在、版权、上下架、阅读权限)
  • 计算价格
  • 创建订单
    • 获取分布式锁
    • 保存订单相关数据,发送订单信息到延时队列
    • 释放锁
  • 返回提交订单的令牌,并存入缓存,过期时间与订单一致

购买会员

  • sm2加密传参、校验参数
  • 校验防重令牌,防止重复提交
  • 查询会员信息,创建订单
  • 保存订单相关数据,发送订单信息到延时队列

取消订单

  • sm2加密传参、校验参数
  • 获取分布式锁(与支付相同)
  • 判断
    • 预支付缓存
    • 支付缓存
  • 根据状态取消/支付订单

FAQ

如何保证数据更新后购物车同步更新

某商品可能存在众多购物车中,商品一旦发生修改,就涉及缓存的更新,大量缓存更新是不可取的。这里借鉴了Redis生成RDB快照时的思路,当用户查询购物车时,判断是否更新购物车。
ps:如何进行判断操作,当修改商品信息后,记录此修改的时间,购物车中同样存储此时间,若两个时间不一致说明商品有修改,需要更新购物车。

购物车商品有效性校验

购物车数据存储在缓存中,正常情况下商品不更新不需要更新购物车,但是有部分数据需要每次验证,例如商品版权信息,带有时效性的信息,这部分时间数据存储在缓存中,在每次查询时需要在内存中进行逻辑判断。

购物车存储数据内容有哪些

方案有两种

  • 只存储商品id等信息,查询时进行关联
  • 存储商品全部信息,查询时判断是否最新

根据两种方案选择合适的即可。

去结算&提交订单区别

去结算:对购物车中选择待购买的商品,后台计算价格、优惠、校验等一系列操作后返回给前端展示。
提交订单:在去结算展示页面添加收货地址等信息后,后台创建订单的操作。

购物车购买和直接购买区别

购物车购买:购物车是缓存数据,需要对数据进行校验正确性。
直接购买:不需要经过购物车,直接查询最新数据进行计算价格购买。
还有一点是,在多端情况下,购物车购买需要添加分布式锁,而直接购买只需要创建订单时添加。

为什么使用分布式锁

在考虑多端情况下,用户在PC和APP同时对商品进行下单,可能存在校验是否购买过、库存数相关内容时校验显示通过,实际不通过的情况。为了避免多端带来的问题,添加了分布式锁。

如何验证订单是否过期

订单创建完成后,会加入到延时队列,在延时队列消费订单前,订单可能进行支付也可能搁置,等到了到期时间后,延迟队列首先对支付源(微信、支付宝)进行关单处理,防止用户支付,关单成功后对订单的状态进行修改即可。
极端情况,用户扫码进行支付途中订单到期,有两种情况:

  • 关单成功,用户扫码支付提示失败。
  • 关单失败,说明用户已支付,需要走成功逻辑。

在关单前查询支付状态,根据状态关单即可。

预支付缓存和支付缓存关系

预支付:缓存时间与订单超时取消时间一致,30min,只存储订单号
支付缓存:每种支付方式只有5分钟时间,存储支付方式相关信息
若预支付缓存不存在,说明订单已超期,无法支付。
支付缓存存在说明曾调起过支付,还未关闭(调起的支付有效时间与此缓存一致)。
ps:在支付篇中重点讲解

防重令牌获取

顾名思义防止重复提交,但是其中也有顺序,例如订单中的令牌都是从结算接口返回的。
购物车、结算的令牌时从接口获取的。
支付可以从订单返回数据中获取,也可以单独请求接口获取

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值