当前位置:网站首页>如何防止重复下单?
如何防止重复下单?
2022-08-04 15:29:00 【InfoQ】
用户下单流程

- 浏览商品:用户查看商品详情
- 加购/结算:用户可以选择直接购买商品,也可以先加入购物车,用户购买的这一步就是结算
- 确认下单:结算完成,就进入了下单页面,
提交订单,这一步就会生成一个订单,然后进入付款页面
为什么会重复下单
- 用户重复提交
- 网络原因导致的超时重试

如何防止重复下单

requestId利用数据库实现幂等
t_orderrequestId
PlaceOrderResVO placeOrder(PlaceOrderReqVO reqVO) {
try {
//下单业务逻辑
……
//生成订单号
String oid=generateOid();
……
//订单落库
Order order = orderMapper.saveOrder(orderDO);
//响应订单
resVO.setOid(order.getOid());
return resVO;
} catch(UniqueKeyViolationException e) {
// 发生了重复异常
// 根据请求号获取订单
Order order = getOrderByRequestId(reqVO.getRequestId());
resVO.setOid(order.getOid());
return resVO;
} catch (Exception e) {
}
}
利用Redis防重
- 就是以
requestId为维度,进行加锁,如果获取锁失败,就抛一个自定义的重复下单异常。
- 如果获取到锁,先check一下,是否已经下单,为了提高性能,下单完成后,也把下单的结果放在Redis缓存里。

public PlaceOrderResVO placeOrder(PlaceOrderReqVO reqVO) {
//加锁
RLock orderLock = redissonClient.getLock(RedisConstant.PLACE_ORDER_LOCK_KEY + reqVO.getRequestId());
//获取锁失败,抛出重复下单异常
if(orderLock.isExistes){
throw new OrderRepeatException();
}
// 加锁
orderLock.lock();
try {
//检查是否已经下单
RBucket<PlaceOrderResVO> orderCache = redissonClient.getBucket(RedisConstant.PLACE_ORDER_LOCK_KEY+reqVO.getRequestId());
if(orderCache.isExistes){
return orderCache.get();
}
//下单业务逻辑
……
//落库
//订单落库
Order order = orderMapper.saveOrder(orderDO);
……
//缓存结果
orderCache.put(resVO);
return resVO;
}
} catch (Exception e) {
//……
} finally {
orderLock.unlock();
}
return resVO;
}
- 为什么获取不到锁的时候要抛异常呢?
边栏推荐
猜你喜欢

NUS颜水成等发布首篇《深度长尾学习》综述

365天挑战LeetCode1000题——Day 049 非递增顺序的最小子序列 贪心

Zheng Qing freshmen school competition and middle-aged engineering selection competition

解决dataset.mnist无法加载进去的情况

Why, when you added a unique index or create duplicate data?

程序猿七夕礼物-如何30分钟给女朋友快速搭建专属语聊房

一文解答DevOps平台的制品库是什么

SAP ABAP SteamPunk 蒸汽朋克的最新进展 - 嵌入式蒸汽朋克

Redis-哨兵模式

使用百度EasyDL实现森林火灾预警识别
随机推荐
C语言写简单三子棋
MySQL select加锁分析
Zheng Qing freshmen school competition and middle-aged engineering selection competition
H5 之 文件流转base64下载
一文解答DevOps平台的制品库是什么
AIX7.1安装Oracle11g补丁33829709(PSU+OJVM)
SublimeText 粘贴图片保存到本地
LeetCode_模拟_中等_498.对角线遍历
我说MySQL联合索引遵循最左前缀匹配原则,面试官让我回去等通知
Resharper 如何把类里的类移动到其他文件
卖家寄卖流程梳理
李沐的深度学习笔记来了!
leetcode: 255 Verify preorder traversal sequence binary search tree
2022年7月国产数据库大事记-墨天轮
西安纵横资讯×JNPF:适配中国企业特色,全面集成费用管控体系
leetcode: 251. Expanding 2D Vectors
【伸手党福利】投影仪初学者入门——投影亮度及幕布选择——从入门到精通
numpy入门详细代码
C# 谁改了我的代码
使用百度EasyDL实现森林火灾预警识别