如何解决幂等性问题

什么是幂等性?

定义:对某个资源进行一次或多次请求后,产生的结果都是一样的。

常见的例子就是前端的表单提交时进行的POST请求,正常预想就是用户填写资料,点击了一次按钮,后端接收后数据库进行一个insert操作。

但试想一下,如果这时我们没有做任何措施,用户点击了一次提交按钮之后又快速点击了一次,这时后端就会再insert一次,从而导致数据出现重复异常。这就是非等幂性的结果。

解决等幂性的核心思想就是如何保证这个接口的执行结果被影响一次,该接口即使后续被调用也不会对结果有影响。

那么相应的解决方案有哪些呢?

  • 进行数据新增操作:

    1. 前端交互控制:我们可以在用户点击按钮后立即取消表单框或退出提交页面,也可以在用户点击按钮后将按钮置为不可点击状态。这种方式是最简便的,但如果遇到懂的用户,对方可以直接发起该接口的多次快速请求来故意破坏

    2. 数据库唯一索引:我们可以为数据表的某些字段设置唯一索引(比如说id字段),让该字段的值唯一。这样如果重复数据提交mysql就会插入失败。

    3. 防重Token:

      这种方式分成两个阶段:申请token阶段和支付阶段。
      第一阶段,在进入到提交订单页面之前,需要订单系统根据用户信息向支付系统发起一次申请token的请求,支付系统将token保存到Redis缓存中,为第二阶段支付使用。
      第二阶段,订单系统拿着申请到的token发起支付请求,支付系统会检查Redis中是否存在该token,如果存在,表示第一次发起支付请求,删除缓存中token后开始支付逻辑处理;如果缓存中不存在,表示非法请求。

  • 进行数据更新操作:

    1. 乐观锁:

      首先在设计数据库表的时候为会有重复提交问题的表加个version字段,每次获取数据的时候后端会一齐带上version,但前端并不展示。在修改数据的时候带上这个字段,每次update操作时进行update table set ***,version = #{version}+1 where version = #{version}SQL操作,如果是重复提交的话,where条件将会因为第一次提交修改而不成立,修改失败说明这是重复的提交,拒绝。


 上一篇
业务场景问题 业务场景问题
1.MySQL主从复制读写分离后,主从之间存在延迟,从库读到了旧数据怎么办? 读写分离中间件:使用专门的读写分离中间件,如MySQL Proxy或MaxScale等,这些中间件可以监控主从延迟,如果达到延迟阈值则将读操作路由到主库或最新的从
2023-08-30 Touko
下一篇 
了解线程池 了解线程池
线程池:线程池就是管理一系列线程的资源池,当有任务时,直接从线程池中拿出已经创建好的线程来处理,处理完后的线程被放回线程池中,并不会被销毁。 优点:线程池能够降低重复创建和销毁线程所来带的资源消耗,由于能在需要时就能获取已经创建的线程,响应
2023-06-09
  目录