1.前言面试中经常出现一道经典的面试题,那就是:如何防止接口重复提交?小编也记住了几种方法,但是一直没有在实战中尝试过。做了很多管理制度,发现这个事情真的没有太重视。最近测试的时候,发现多次提交会保存两条数据,这样会导致程序出现问题!问题出现了,我们来解决吧!!本方案针对高并发但不高的情况,适用于一般管理系统,给出方案!!高并发建议加分布式锁!!先说说什么是幂等?2、什么是幂等性?接口幂等性是指用户对同一操作发起一次请求或多次请求的结果是一致的,不会因为多次点击而产生副作用;比如经典的支付场景:用户购买了商品支付扣费成功,但是返回结果的时候网络异常。这个时候,钱已经被扣了。用户再次点击该按钮,此时会进行第二次扣款。结果返回成功,流水记录也变成了条条,不保证接口的幂等性;可谓是:商家高兴,买家大骂!防止重复提交接口,这个是必须要做的!3.REST风格与幂等性用四种常用类型解析!REST是否支持幂等SQL示例GETisSELECT*FROMtableWHERid=1PUTisUPDATEtableSETage=18WHEREid=1DELETEisDELETEFROMtableWHEREid=1POSTisnotINSERTINTOtable(id,age)VALUES(1,21)那么我们要解决的就是POST请求了!4.解决思路大概是主流的解决方案:token机制(前端在请求头上携带标识,后端校验)锁机制数据库悲观锁(锁表)数据库乐观锁(版本号受控))业务层分布式锁(加分布式锁redisson)全局唯一索引机制redisset机制前端按钮加限制小编的解决方案是redis的set机制!对于同一个用户,任何与POST存储相关的接口在1秒内只能提交一次。完全用后台控制,前端可以限制,但是体验不好!后端使用自定义注解为需要反幂等的接口添加注解,使用AOP切片降低与业务的耦合!获取分片中用户的token、user_id、url,组成redis的唯一键!第一次请求会先判断key是否存在。如果不存在,则在redis中添加一个主键key,并设置过期时间;如果有异常,会主动删除key。如果没有删除失败,等待1s,redis会自动删除。时间错误是可以接受的!第二次请求来的时候先判断key是否存在,如果存在则重复提交,返回保存的信息!5.SpringBoot实际版本为2.7.4。1、导入依赖org.springframework.bootspring-boot-starter-data-redisorg.projectlomboklombok1.18.2org.springframework.bootspring-boot-starter-aoporg.springframework.bootspring-boot-starter-webcom.alibabadruid-spring-boot-starter1.1.16org.springframework.boot</groupId>spring-boot-starter-jdbcmysqlmysql-connector-javacom.baomidoumybatis-plus-boot-starter3.5.1org.springframework.bootspring-boot-starter-test测试2、编写ymlserver:port:8087spring:redis:host:localhostport:6379password:123456datasource:#使用阿里的Druidtype:com.alibaba.druid.pool.DruidDataSourcedriver-class-name:com.mysql.cj。jdbc.Driverurl:jdbc:mysql://127.0.0.1:3306/test?serverTimezone=UTC用户名:root密码:3、redis序列化/***@authorwangzhenjun*@date2022/11/1715:20*/@ConfigurationpublicclassRedisConfig{@Bean@SuppressWarnings(value={"unchecked","rawtypes"})publicRedisTemplate