幂等性校验(订单重复提交问题)
一、幂等性校验的概念
幂等性指对同一操作的多次执行结果与单次执行结果一致。在订单系统中,重复提交可能导致重复扣款、重复发货等问题,需通过幂等性校验避免。
二、常见解决方案
1、数据库唯一索引
在订单表中为业务唯一字段(如订单号、流水号)添加唯一索引,重复插入时会触发数据库报错。需捕获异常并返回友好提示。
2、Token 机制
- 页面加载时生成唯一 Token 并存入服务端(如 Redis)。
- 提交订单时携带 Token,服务端校验后删除 Token。重复提交时因 Token 失效而拦截。
3、乐观锁
通过版本号控制数据更新,仅当版本匹配时才执行操作。例如:
UPDATE orders SET status = 'paid', version = version + 1
WHERE order_id = '123' AND version = 1;
分布式场景下的实现
1、分布式锁
使用 Redis中Redisson基于lua脚本实现分布式锁 或 Zookeeper 实现分布式锁,确保同一订单在同一时间只能被处理一次。
2、消息队列去重
MQ 消息携带唯一业务 ID,消费时通过 Redis 记录已处理消息 ID,实现重复消息过滤。
实践建议
- 结合前端防重(如提交按钮禁用)和后端校验。
- 关键业务操作需记录日志,便于排查问题。
- 根据业务复杂度选择方案,简单场景用 Token 或唯一索引,高并发场景引入分布式锁。