问题描述:
多笔合并支付,待付款的订单,手动取消时积分退回正常,但等待30min自动取消时,积分部分商品未退回。
复现步骤:
1、线上积分账户余额:158.24,三个商品一起下单,该笔订单未支付成功,订单状态为待付款;
2、等到付款时间失效,未支付订单取消,积分退回,积分账户余额:110.24,且总的积分丢失48;
3、发现该订单的三个商品中,有一个商品使用了48积分。
01. 猜测可能的原因
✅ 原因1:自动取消与手动取消逻辑不一致
• 手动取消:触发即时积分回退逻辑。
• 自动取消:可能依赖定时任务,未正确调用积分回退接口,或任务执行失败。
✅ 原因2:订单状态机缺陷
• 自动取消时,订单状态未正确更新为“已取消”,导致积分回退条件不满足。【此项排除】
✅ 原因3:积分回退事务未完整执行
• 自动取消流程中,积分回退可能与其他操作(如库存恢复)在同一事务,若部分失败则回滚。
✅ 原因4:幂等性处理不当
• 自动取消可能因重试机制导致重复调用积分回退接口,但未做幂等控制,部分请求被丢弃。
✅ 原因5:商品级积分回退缺失
• 部分商品(如促销商品)可能使用独立积分规则,自动取消时未覆盖这类特殊商品。【此项排除】
02.解决方案
1. 逻辑修复方案
(1)统一取消订单的积分回退逻辑*
• 修改点:
• 无论手动取消还是自动取消,均调用 同一积分回退服务。
(2)增强自动取消的可靠性
• 方案A(推荐):
自动取消时,先持久化“取消事件”到数据库,再通过消息队列(如Kafka)触发积分回退,确保最终一致性。
• 方案B:
定时任务增加失败重试机制,并记录日志供人工核查。
(3)事务与幂等性优化
• 事务拆分:
• 积分回退与库存恢复拆分为独立事务,避免相互影响。
• 幂等控制:
• 积分回退接口增加 order_id 幂等键,防止重复执行。
2. 数据修复与验证
(1)补偿未退回的积分*
遍历订单中所有商品,按商品原始积分抵扣比例回退,SQL修复。
(2)日志与监控
• 关键日志:
• 记录自动取消任务的执行时间、订单ID、积分回退结果。
• 监控报警:
• 对 status=CANCELED但points_refunded=0 的订单设置告警。
03.预防措施
自动化测试覆盖
• 新增测试用例:模拟自动取消订单,验证积分是否100%退回。状态机流程图评审
• 确保所有取消路径(手动/自动/超时)均触发积分回退。对账机制
• 每日定时核对订单系统与积分系统的数据一致性。
04.测试流程优化
问题发现及确认:
1、接触该项目后,日常熟悉功能、测试项目都会发现历史问题,故每周设置探索性测试时间不低于3h,发现潜在问题;
2、进行订单取消功能测试时,发现此问题,并重新梳理该功能模块的逻辑,编写详细的用例,进行全流程回归,尽可能清理掉历史问题。