此文适用情况
本次解决是对于高并发不高的情况,适用于一般的管理系统,给出的解决方案!!高并发的还是建议加分布式锁!!
什么是幂等性
接口幂等性就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因 为多次点击而产生了副作用; 比如说经典的支付场景:用户购买了商品支付扣款成功,但是返回结果的时候网络异常,此时钱已经扣了,用户再次点击按钮,此时会进行第二次扣款,返回结果成功,用户查询余额返发现多扣钱了,流水记录也变成了条,这就没有保证接口的幂等性; 可谓:商家美滋滋,买家骂咧咧!!
防接口重复提交,这是必须要做的一件事情!!
REST风格与幂等性
以常用的四种来分析哈!
| REST | 是否支持幂等 | SQL例子 |
| GET | 是 | SELECT * FROM table WHER id = 1 |
| PUT | 是 | UPDATE table SET age=18 WHERE id = 1 |
| DELETE | 是 | DELETE FROM table WHERE id = 1 |
| POST | 否 | INSERT INTO table (id,age) VALUES(1,21) |
所以我们要解决的就是POST请求!
解决思路
- token机制(前端带着在请求头上带着标识,后端验证)
- 加锁机制
-
- 数据库悲观锁(锁表)
- 数据库乐观锁(version号进行控制)
- 业务层分布式锁(加分布式锁redisson)
- 全局唯一索引机制
- redis的set机制
- 前端按钮加限制
本文为redis的set机制
后端通过自定义注解,在需要防幂等接口上添加注解,利用AOP切片,减少和业务的耦合! 在切片中获取用户的token、user_id、url构成redis的唯一key! 第一次请求会先判断key是否存在,如果不存在,则往redis添加一个主键key,设置过期时间;
如果有异常会主动删除key,万一没有删除失败,等待1s,redis也会自动删除,时间误差是可以接受的! 第二个请求过来,先判断key是否存在,如果存在,则是重复提交,返回报错信息!!
实战