订单的状态
状态 | 进入操作 | 进入条件 |
---|---|---|
草稿 | 新建订单 ,保存订单;提交审批失败,审批拒绝 | 新建订单:插入新订单, 保存订单:修改订单;提交审批失败:修改订单,审批拒绝:修改订单 |
待审批 | 提交审批 | 修改库存数量,修改订单状态,插入新审批数据 |
待提交 | 审批通过 | 修改审批系统,修改订单系统 |
待执行 | 点击“提交”按钮 | 修改库存系统,修改订单系统 |
已完成 | 点击“完成”按钮 | 修改订单系统,写入财务系统 |
关键问题的设计
提交订单的数据一致性
- 向库存系统发送扣减库存请求,库存系统扣减库存数量(使用排它锁保证),并通过消息队列插入库存扣减操作日志,请求失败时,终止操作(原因:库存不足,系统异常,网络原因)。
- 库存扣除成功后,修改订单状态为“待审批”,并通过消息队列插入库存扣减成功日志。修改订单状态失败时,终止操作,并向库存系统发送恢复扣减库存请求(订单系统无需处理该请求的失败)。
- 库存系统处理扣减库存请求时,生成库存扣减操作id并返回给订单系统,订单系统发送恢复扣减库存请求时传入该id,库存系统根据扣减操作日志恢复库存数量,并通过消息队列插入库存扣减已恢复日志。
- 库存系统需要定时扫描日志,如果一条操作日志没有对应的完成日志(根据操作id匹配),则根据操作日志记录恢复库存,并通过消息队列插入库存扣减已恢复日志。
通过消息队列的顺序消息特性保证库存扣减操作日志的顺序,并由消息队列消费端保证操作日志写入的幂等性(保证每次扣减库存操作只有一条扣减记录和完成记录),成功日志和已恢复日志属于完成记录。
消息队列中消息堆积时,日志写入延迟,导致部分操作日志不完整,所以定时扫描任务应定义合理的时间偏移,仅扫描能确保正确的日志,并且在消息堆积较为严重时,及时停止定时扫描任务 。