前言
我看到这块知识点的时候也是像你一样一脸懵比这个是啥玩意
哈哈哈,不要慌我带你上高速
啥是幂等性
在HTTP/1.1中,对幂等性进行了定义。它描述了一次和多次请求某一个资源对于资源本身应该具有同样的结果(网络超时等问题除外),即第一次请求的时候对资源产生了副作用,但是以后的多次请求都不会再对资源产生副作用。
用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用,数据库的结果都是唯一的,不可变的。
幂等性啥时候需要触发
- 前端用户表单的提交由于网络的原因没有显示提示信息,用户重复发送
- 恶意的请求接口造成多次重复无用的请求
- 由于网络的设计,http协议中有一个超时重传的机制,再一次发送请求
- 消息队列中的消息重复的消费
发现没有这里的情况都是重复的发送或者处理已经在处理中的数据
所以我们就需要一些的方案来解决这些问题
而且这些操作后果造成的持久化的影响就是数据库的四个层面和混合使用的情况
- 增
如果没有唯一的id 一般使用token令牌
- 删
如果数据库中有唯一主键 那么无需做其他操作,如果没有唯一主键就需要使用token令牌来维系幂等性
- 改
update中最常见的达到幂等性的方案就是乐观锁
- 查
因为对于业务代码来说 s 锁是共享的 天然幂等所以无需操作 (这里的查真的只有查没有奇奇怪怪的操作)
- 混合操作
token令牌yyds
具体的操作
token令牌
执行步骤
- 先请求后端的token接口
- 将生成的token返回前端并且将token存到缓存中
- 客户端请求业务的时候先带上之前返回的token
- 进行判断 缓存中的token是否存在
- 如果 没有则说明这一次的请求无效返回即可
- 如果 查询到这一个token那么执行后续的业务逻辑并且在返回之前将token删除
注意这里的token删除的时机有两个选择
- 在判断通过之后立刻删除
这一个操作可能出现执行业务代码的时候出错了 客户端没有收到成功的信息
- 在返回成功信息之前删除
这一个操作可能出现在删除token之前就出错导致业务代码执行过了 但是token没有删除的情况
比较上述的方案 造成影响比较小的是
在判断通过之后立刻删除
因为对于系统来说相比于客户端重复请求一次 重复执行业务代码可能造成不可逆可影响
唯一主键约束
执行步骤
- 客户端发送请求插入一条数据
- 服务端生成一个分布式id
- 将生成的id作为主键插入数据库中
在java中可以通过雪花算法快速生成分布式id
可以使用mybaties-plus中的@TableId表示分布式id
分布式id
生成的id在分布式系统中也是唯一的
也就是通过这个算法生成的id不存在重复[概率比pdd砍价成功还小]
乐观锁
执行步骤
每一次执行业务之前先查询version 让后更新查看version 是否一致
简单介绍一下乐观锁和悲观锁
- 乐观锁
对于情况很乐观,认为在我之前没有线程操作过这一条数据
所以这个锁是不会锁数据的
它保证一致性是通过特殊的字段 version 来保证的
每一次更新的时候都会比较这一个version 是否改变了 没有改变就执行操作 相反如果比较不同就不执行操作返回 - 悲观锁
对于情况很悲观, 认为在我之前一定有线程操作了这一条数据
于是它进行更新的时候会上锁
它保证一致性的方法非常粗暴就是保证线程的执行过程是串行的
结语
其实还有其他一大堆的实现方式 比如
防重表和分布式锁
而分布式锁
我会再开一篇文章来介绍它