如何防止重复下单

一:重复下单与幂等性问题

用户在下单页面进行下单时,由于用户点击下单按钮 多次 、或者 重试策略导致在订单服务中接收到了 两次同样 的下单请求

什么情况下会重复下单

  1. 用户短时间内多次点击下单按钮
  2. 超时重试
  3. 用户APP强退/闪退之后重新下单

重复下单问题,本质上,就是下单操作的幂等性问题,说到底,就是接口幂等性。

二:如何解决重复下单问题

方案一:提交订单按钮置灰
浏览器端去拦住一部分请求,减少后端服务器的处理压力,达到过滤流量的效果。
方案一优点:简单。基本可以防止重复点击提交按钮造成的重复提交问题。
方案一缺点:前进后退操作,或者F5刷新页面等问题并不能得到解决。因为服务端这里没有加限制

方案二:请求唯一ID+数据库唯一索引约束(数据库层面做幂等)

  1. 当用户进入订单提交界面的时候,调用后端获取请求唯一ID,并将唯一ID值埋点在页面里面。
  2. 当用户点击提交按钮时,后端检查这个唯一ID是否用过,如果没有用过,继续后续逻辑;如果用过,就提示重复提交。
  3. 最关键的一步操作,就是把这个唯一ID 存入业务表中,同时设置这个字段为唯一索引类型,从数据库层面做防止重复提交

缺点:DB层面约束,并发量低

方案三:redis分布式锁 + token 推荐

  1. 用户点击提交订单按钮,服务端接受到请求后,通过规则计算出本次请求唯一ID值
    • 接口唯一ID:应用名+接口名+方法名+请求参数签名(请求header、body参数,取SHA1值)
  2. 使用redis的分布式锁服务,对请求 ID 在限定的时间内尝试进行加锁,如果加锁成功,继续后续流程;如果加锁失败,说明服务正在处理,请勿重复提交。
  3. 最后一步,如果加锁成功后,需要将锁手动释放掉,以免再次请求时,提示同样的信息。

思考:同一个用户可能就是想买两次相同的产品,可能说先买了一个,刚买完发现需要两个,再买一个同一个产品,所以这时候我们设计不能不让用户买,这种情况就是说能不能对唯一ID设计上来区分这次请求,如果说不能区分,那在我们业务上redis分布式锁的时间范围这要去设计准确点,比如说一次下单到支付需要多长时间,锁的时间设置为比这个时间稍大些,不能时间太长,这样用户第二次购买发现不让重复操作。当然前面只是一种思路,还比如能不能经过判断后唯一ID相同,但是不知道用户是不是想重复购买,这时候可以给用户提示:发现购买相同,是否继续,继续那就放行,不继续就拦截。

代码实现思路:使用AOP实现对业务token的无侵入生成
可以定义注解,在生成订单的方法上加该注解,AOP的逻辑就是生成唯一token,然后加锁,看加锁能不能成功,成功则放行执行后续逻辑,失败则表示重复下单,拦截。


万能方案
一锁二判三更新
一锁:先加锁,可以加分布式锁、悲观锁都可以,但是一定是一个互斥锁
二判:进行幂等性判断,可以基于状态机业务流水表数据库唯一索引等,进行重复操作的判断。
三更新:对数据进行更新,将数据进行持久化。

三:总结

防止重复下单,本质上就是先做重复判断,然后服务端做好幂等性控制,结合实际业务场景选择相应的方案。

相关推荐

  1. 如何防止重复

    2024-04-21 10:14:02       15 阅读
  2. SpringBoot表防止重复提交

    2024-04-21 10:14:02       17 阅读
  3. springboot防止重复提交

    2024-04-21 10:14:02       9 阅读
  4. 功能问题:如何防止接口重复请求?

    2024-04-21 10:14:02       8 阅读
  5. 002 springboot redis 防止重复提交

    2024-04-21 10:14:02       11 阅读
  6. Spring Cloud项目如何防止重复提交(自定义注解)

    2024-04-21 10:14:02       36 阅读
  7. 防止重复调用

    2024-04-21 10:14:02       8 阅读
  8. HTML5中form表防止重复提交的两种方法

    2024-04-21 10:14:02       41 阅读
  9. 分布式防止重复请求或者高并发防止重复提交

    2024-04-21 10:14:02       7 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-21 10:14:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-21 10:14:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-21 10:14:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-21 10:14:02       20 阅读

热门阅读

  1. 【基础】伐木工

    2024-04-21 10:14:02       14 阅读
  2. 【无标题】

    2024-04-21 10:14:02       10 阅读
  3. Docker

    2024-04-21 10:14:02       14 阅读
  4. Docker

    Docker

    2024-04-21 10:14:02      12 阅读
  5. liteide 找不到 go 路径错误修复

    2024-04-21 10:14:02       13 阅读
  6. random模块

    2024-04-21 10:14:02       12 阅读
  7. 医疗实施-项目管理03-项目启动会

    2024-04-21 10:14:02       12 阅读
  8. 记一个闭包导致的内存泄漏问题

    2024-04-21 10:14:02       11 阅读
  9. ResouceUtils.getFile()取不到Jar中资源文件源码

    2024-04-21 10:14:02       13 阅读