【项目总结】易到家家政服务平台 —— 订单管理(6)

订单状态流程

订单状态流转图:
在这里插入图片描述
订单状态:
在这里插入图片描述
服务单状态:
在这里插入图片描述

分库分表

分库方案

设计三个数据库,根据用户id哈希,分库表达式为:db_用户id % 3

在项目后期虽然存在数据迁移的问题,但总体来说很长一段时间不需要考虑
在这里插入图片描述

分表方案

根据订单范围分表,0—1500万落到table_0,1500万—3000万落到table_1,依次类推。根据范围分表不存在数据库迁移问题,方便系统扩容。

分表表达式:orders_${(int)Math.floor(id % 10000000000 / 15000000)}

整体方案

分库方案:
设计三个数据库, 根据服务人员id哈希,分库表达式:jzo2o-orders-${serve_provider_id % 3}

分表方案:
根据订单范围分表,0—1500万落到table_0,1500万—3000万落到table_1,依次类推。
orders_serve_${(int)Math.floor(id % 10000000000 / 15000000)}
在这里插入图片描述

创建订单

订单号生成规则

本项目订单号生成规则如下:
19位:2位年+2位月+2位日+13位序号
例如:2311011000000000001

实现方案:
1、前6位通过当前时间获取。
2、后13位通过Redis的INCR 命令实现。

价格计算规则

分两种情况:
未使用优惠券:
实际支付金额=订单总金额
订单总金额=服务单价 * 数量

使用优惠券:
实际支付金额=订单总金额-优惠金额。
订单总金额=服务单价 * 数量
优惠金额:调用优惠券服务接口进行计算,分两种情况:满减和折扣。

优惠券核销(分布式事务)🌟

下单与优惠券核销组成分布式事务,进行分布式事务控制,根据需求分布式事务控制满足AP,即强调的是可用性,允许出现短暂不一致,最终达到数据一致性。

Seata控制分布式事务

Seata事务管理中有三个重要的角色:

  • TC (Transaction Coordinator) - 事务协调者:维护全局和分支事务的状态,协调全局事务提交或回滚。
  • TM (Transaction Manager) - 事务管理器:定义全局事务的范围、开始全局事务、提交或回滚全局事务。
  • RM (Resource Manager) - 资源管理器:管理分支事务处理的资源,与TC交互注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
    在这里插入图片描述
  1. 事务管理器(TM)开启全局事务
  2. 事务管理器(TM)请求RM执行分支事务
    下单RM:先向事务协调器(TC)注册下单分支事务,并执行sql(记录undo log),并向TC报告事务状态
    undo log:用于回滚事务使用,下单sql是插入记录,根据undo log会生成反向sql删除记录,通过执行反向sql实现回滚事务。
    优惠券RM:先向事务协调器(TC)注册优惠券核销分支事务,并执行sql(记录undo log),并向TC报告事务状态
  3. 事务管理器(TM)请求TC提交全局事务
  4. TC检查分支事务状态,如果发现都成功则请求每个RM提交事务(删除undo log),如果发现其中有失败记录则请求每个RM回滚事务,RM回滚事务的方法是通过undo log执行提交事务的反向sql。

防止订单重复提交

  1. 前端防重复提交
    禁用提交按钮: 在用户点击提交按钮后,立即将按钮禁用,防止用户多次点击。
    显示加载中状态: 提交按钮点击后,显示加载中状态,防止用户再次点击。

  2. 后端防重复提交
    使用分布式锁:以用户id+服务id作为分布式锁锁定下单接口10秒,10秒内该用户不能再次下同一个服务的订单。

订单支付

查询订单

单条订单查询优化

根据订单Id查询缓存信息,先从缓存查询如果缓存没有则查询快照表的数据然后保存到缓存中。缓存设置了过期时间是30分钟。

当订单状态变更,此时订单最新状态的快照有变更,会删除快照缓存,当再次查询快照时从数据库查询最新的快照信息进行缓存

用户端订单列表优化🌟

使用滚动查询,一次查询指定数量的记录,不用进行count查询,省去count查询的全标扫描消耗。

首先在订单表使用排序字段sort_by作为滚动ID,滚动ID是一种递增的序列号,是按开始服务时间+订单生成时间计算生成

然后根据查询条件查询符合条件的订单ID,这里使用覆盖索引优化的方法。最后对订单信息进行缓存,使用redis的hash结构存储订单信息。

保证缓存一致性:
当用户创建新订单删除该用户在redis的hash结构中的数据。
当用户的 订单状态发生变更则删除redis中hash结构中的订单数据库。

 sort_by          bigint                             null comment '排序字段,serve_start_time秒级时间戳+订单id后六位',

运营端订单列表优化

运营端订单列表由于访问量不大这里无需使用缓存,实现方案是首先通过覆盖索引查询符合条件的订单ID,再根据订单ID查询聚集索引拿到数据。

我们根据查询条件创建的联合字段索引是非聚集索引,先从非聚集索引中查询到符合条件的ID,再根据订单ID从聚集索引中查找数据。

取消订单

  1. 根据上边的需求,下边分析订单取消功能。

取消待支付的订单:
最终的结果是更改订单状态为已取消,因为没有支付所以不涉及退款。
消派单中的订单:
用户和运营人员都可以取消订单,订单状态改为已关闭。
到达服务时间还没有派单成功系统自动取消。
取消订单后自动退款。
删除抢单池记录。

  1. 用户权限
    普通用户:可取消待支付、派单中、待服务的订单。
    运营人员:可取消除待支付状态下的所有订单。

策略模式🌟

针对不同场景下取消订单的逻辑定义一个策略类,不同场景只需要修改或者增加策略实现类即可。
在这里插入图片描述

/**
 * 订单取消策略接口
 *
 * @author itcast
 * @cre
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值