文章目录

  • 前言
  • 1、方案实现
    • 1.1、给数据库表增加唯一键约束
    • 1.2、编写获取请求唯一ID的接口
    • 1.3、业务提交的时候,检查唯一ID
  • 2、小结

前言

对于投入运营的软件系统(商城、物流、工厂等),最近小编在巡检项目数据库的时候,发现某些表存在不少的重复数据,对于这样的脏数据,初步分析大致的来源有以下可能:

1.由于用户误操作,多次点击表单提交按钮
2.由于网速等原因造成页面卡顿,用户重复刷新提交页面
3.黑客或恶意用户使用 postman 等网络工具,重复恶意提交表单

这些情况都可能会导致表单重复提交,造成数据重复,比如订单表,重复提交订单数据所造成的问题,可能不仅仅是数据上的混乱,也会造成业务混乱。

那么问题来了,我们该如何防止用户重复提交数据呢?

方案实践如下!

1、方案实现

下面我们以防止重复提交订单为例,向大家介绍最简单的、成本最低的解决办法。

我们先来看一张图,这张图就是本次方案的核心流程图。

实现的逻辑,流程如下:

1.当用户进入订单提交界面的时候,调用后端获取请求唯一ID,并将唯一ID值埋点在页面里面

2.当用户点击提交按钮时,后端检查这个唯一ID是否用过,如果没有用过,继续后续逻辑;如果用过,就提示重复提交

3.最关键的一步操作,就是把这个唯一ID 存入业务表中,同时设置这个字段为唯一索引类型,从数据库层面做防止重复提交
防止重复提交的大体思路如上,实践代码如下!

1.1、给数据库表增加唯一键约束

以订单表为例,新增一个request_id字段,并设置为唯一约束,结构如下:

CREATE TABLE tb_order (id bigint(20) unsigned NOT NULL,order_no varchar(100) NOT NULL,....request_id varchar(36) NOT NULL,PRIMARY KEY (id),UNIQUE KEY uniq_request_id (request_id) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

1.2、编写获取请求唯一ID的接口

@RestController
@RequestMapping("api")
public class CommonController {/*** 获取getRequestId* @return*/@RequestMapping("getRequestId")public ResResult getRequestId(){String uuid = UUID.randomUUID().toString();return ResResult.getSuccess(uuid);}
}

1.3、业务提交的时候,检查唯一ID

@RestController
@RequestMapping("order")
public class OrderController {@Autowiredprivate OrderService orderService;/*** 下单* @param request* @return*/@PostMapping(value = "order/confirm")public ResResult confirm(@RequestBody OrderConfirmRequest request){//调用订单下单相关逻辑if(StringUtils.isEmpty(request.getRequestId())){return ResResult.getSysError("请求ID不能为空!");}if(request.getRequestId().length() != 36){return ResResult.getSysError("请求ID格式错误!");}//检查当前请求唯一ID,是否已经存在,如果存在,再提交就是重复下单Order source = orderService.queryByRequestId(request.getRequestId());if(Objects.nonNull(source)){return ResResult.getSysError("当前订单已经提交成功,请勿重复提交");}orderService.confirm(request);return ResResult.getSuccess();}
}

如果是并发请求也不用担心,因为数据库表已经设置了唯一索引,尤其只有一条有效数据会插入成功,可以防止重复的数据产生。

2、小结

对于下单流量不算高的系统,可以采用这种请求唯一ID+数据表增加唯一索引约束的方式,来防止接口重复提交!
虽然简单粗暴,但是十分有效!

可能有的人会问,看上面的代码生成请求唯一 ID 很简单,为啥不直接前端生成一个请求唯一ID,然后提交呢?

之所以把获取请求唯一ID的生成规则放在后端,好处就是生成规则可以自己定义,也并不一定要用uuid来生成,也可以用雪花算法,或者自己设计一套计算规则,保证当前业务提交时请求ID是唯一的,比如事先生成唯一的订单号,作为请求唯一ID,然后再提交,规则放在后端来生成,会更加灵活!

解决方式一:https://blog.csdn.net/weixin_47316183/article/details/130180165?spm=1001.2014.3001.5502
解决方式二:https://blog.csdn.net/weixin_47316183/article/details/130180299?spm=1001.2014.3001.5502
解决方式三:https://blog.csdn.net/weixin_47316183/article/details/130180446?spm=1001.2014.3001.5502

参考:https://www.cnblogs.com/dxflqm/p/16914651.html

SpringBoot解决用户重复提交订单(方式一:通过唯一索引实现)相关推荐

  1. php防止订单重复计算,php防止用户重复提交表单

    我们提交表单的时候,不能忽视的一个限制是防止用户重复提交表单,因为有可能用户连续点击了提交按钮或者是攻击者恶意提交数据,那么我们在提交数据后的处理如修改或添加数据到数据库时就会惹上麻烦. 效果图: 那 ...

  2. SpringBoot如何防止重复提交--use

    参考文章:SpringBoot如何防止重复提交 SpringBoot利用AOP防止请求重复提交 场景:同一个用户在2秒内对同一URL的提交视为重复提交. 思考逻辑: 1.从数据库方面考虑,数据设计的时 ...

  3. 如何解决ajax重复提交的问题

    如何解决ajax重复提交的问题 参考文章: (1)如何解决ajax重复提交的问题 (2)https://www.cnblogs.com/xuyan1/p/6256876.html 备忘一下.

  4. 如何防止用户重复提交表单

    我们提交表单的时候,不能忽视的一个限制是防止用户重复提交表单,因为有可能用户连续点击了提交按钮或者是攻击者恶意提交数据,那么我们在提交数据后的处理如修改或添加数据到数据库时就会惹上麻烦. 那么如何规避 ...

  5. SpringBoot + Redis 解决海量重复提交问题

    作者 | 慕容千语 来源 | https://www.jianshu.com/p/c806003a8530 前言 在实际的开发项目中,一个对外暴露的接口往往会面临很多次请求,我们来解释一下幂等的概念: ...

  6. 客户端服务端防止用户重复提交表单

    一.什么是表单重复提交? 当网络有延迟时,用户提交的表单等数据还没有完成此次提交,但用户又多次点击提交,造成用户数据在数据库或存储中被提交多次. 利用线程延迟,简单模拟重复提交. 表单页面为form. ...

  7. 关于防止表单form重复提交的方式

    表单重复提交: 1.第一种:添加以后刷新页面(刷新的是Servlet) 2.第二种:重复点击提交按钮. * 使用令牌机制:(防止表单重复提交) * 在表单页面中 生成一个令牌 * 将这个令牌保存在se ...

  8. 合作开发收费系统——临时表解决用户重复登录问题

         用户重复登录问题,是指同一个用户能够用自己的账户和密码能够同时多次登录.这样的情况在实际使用中是不允许的,就跟QQ.飞信一样,如果你已经登录,等到再次登录的时候,系统就会提醒你" ...

  9. Vue实现订单确认界面禁止浏览器返回操作导致重复提交订单的问题

    哈喽  大家好啊 最近遇到一个问题,就是在提交订单成功后的页面,然后用户去浏览器返回,就导致又提交了一次 然后就想到了如果提交成功页面,就阻止浏览器返回操作 主要实现如下: 1.在mounted的钩子 ...

最新文章

  1. 我佛了!用KNN实现验证码识别,又 Get 到一招!
  2. 提取指定的PDF表格保存到Excel
  3. 前端遍历导致查询数据时间过长_OLAP 服务器,空间换时间可行吗?
  4. openjpa_OpenJPA:内存泄漏案例研究
  5. 求出该数组中特定元素的和,特定元素是指个位和十位不包含7的偶数。
  6. ceph auth get_CPB羽梦幻境体验展来了!快来GET限量产品!
  7. layui.use 在a标签内onclick调用
  8. c语言推箱子代码_C语言烂大街的东西都学不会!C语言多关卡推箱子制作教程
  9. 拓端tecdat|Python支持向量回归SVR拟合、预测回归数据和可视化准确性检查实例
  10. linux内核编程-内核态文件操作
  11. Anaconda快速安装pytorch几分钟离线快速安装一定可行 下载缓慢conda install offline pytorch cudatoolkit slowly
  12. 云豹直播系统源码搭建部署教程
  13. 使用pdf编辑器如何旋转页面
  14. Electron如何修改图标
  15. C语言第1讲——基本编程知识
  16. 新一轮的XNA学习开始
  17. 部门 2016 总结
  18. 苹果cms10的一次尝试发现了苹果cms10被挂马极有可能是苹果cms作者故意的js漏洞或后门导致
  19. 【OBS】解决OBS推两个rtmp流 + 带时间戳问题
  20. uview Checkbox 复选框每一项增加删除功能

热门文章

  1. android如何拨打电话
  2. 学习笔记(16):重叠元素
  3. 没有技术说明文档的开源都是耍流氓:微软Roslyn编译即服务在CIIP中具体应用(上)...
  4. SVN插件 for VS--VisualSVN
  5. 如何把word文件压缩到最小
  6. 《STL源码剖析》-- stl_stack.h
  7. 支持向量机(SVM)入门理解与推导
  8. Linux 设置 FQDN
  9. android 百度地图获取两个坐标的实际路线距离
  10. validator校验注解