商城下单接口被认为是整个项目中最复杂与最须谨慎处理的一个接口,为大家梳理下主链的通用逻辑与伪代码,供参考与启发。
1. 防重提交
场景:前端下单按钮重复点击导致订单创建多次。
处理该问题在前端与与后端都应有限制。
这里采用token令牌机制避免,下单前先获取令牌-存储redis,下单时⼀并把token提交并检验和删除-lua脚本。
String script = "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";
主代码:
Long result = redisTemplate.execute(new DefaultRedisScript<>(script,Long.class), Arrays.asList(String.format(CacheKey.SUBMIT_ORDER_TOKEN_KEY,loginUser.getId())),orderToken);
if(result == 0L){
throw new BizException(BizCodeEnum.ORDER_CONFIRM_TOKEN_EQUAL_FAIL);
}
2.用户微服务-确认收货地址
获取用户收货地址(不做赘述)
3.商品微服务-获取最新购物项和价格
获取用户购物车的相关信息
4.订单验价
4.1 统计商品总价格
4.2 获取用户拥有的优惠券,计算是否满足满减
4.3 锁定优惠券
更改优惠券记录表状态,在优惠券task中新增记录行,将消息投递到rabbitmq。
5.锁定商品库存
更新商品表lock_stock状态,在商品task中新增记录行,将消息投递到rabbbitmq。
6.创建订单对象
创建订单和订单项,将消息投递到rabbitmq,用于自动关单。
7.创建支付信息-对接三方支付
注意:锁库存和消费券的消息是根据订单状态来进行的,故前两者设置的ttl需大于订单的ttl。