针对重复请求问题:使用token机制+(redis+setnx)/(redis+set)的方式
针对数据重复问题:使用代码逻辑+唯一索引/锁机制的方式
针对响应一致性问题:不要设计响应不一致的接口 todo
针对分布式并发问题:使用分布式锁
接口重复请求:用户重复请求接口
接口超时重试:dubbo等框架的超时重试机制
消息重复消费:MQ等框架的消息重复消费造成多次执行消费代码
维基百科:多次调用方法或者接口不会改变业务状态,可以保证重复调用的结果和单次调用的结果一致
- 对接口的n次请求的响应是一致的,响应结果与请求次数无关
- 考虑重复请求对数据的影响,对请求方的影响,对用户的影响
- 接口幂等性,既要避免产生重复数据之外,还要求每次请求都返回一致的结果
缺点:不适用于高并发场景,高并发场景下依然会产生重复数据
增加 *** 作说明:
对数据有唯一性要求,则不允许出现重复数据,n次请求只有首次请求增加成功,后续请求是重复请求
方式:
代码逻辑:增加前先查找,不存在则增加,存在则响应已存在
说明:
删除必须加上limit,已知delete tableName
将删除整个表的数据
方式:
代码逻辑:删除前先查找,存在才删除,不存在则不进行删除 *** 作;删除必须带上limit
说明:
将reqVO赋值给PO即将请求赋值给数据库中查询得到的对象,避免直接使用reqVO更新数据库,影响了未更新的自带
方式:
代码逻辑:先查找再更新,存在则将reqVO赋值给PO再更新,不存在则不进行更新 *** 作
查询一般不存在接口幂等性问题,只要数据不变n次查询结果都是一致的
方案/唯一索引 单表+唯一索引说明:
对数据有唯一性要求,则不允许出现重复数据,n次请求只有首次请求增加成功,后续请求是重复请求
方法:
唯一索引:表中某个字段加上唯一索引,避免对数据造成影响
缺点:
- 无法解决假删除问题
- 假删除字段加到组合唯一索引中也无法解决问题
- 假删除字段没加入组合唯一索引:删除之后,无法再次插入
- 假删除字段是时间类型加入组合唯一索引:可以一直重复插入
- 假删除字段是bool类型加入组合唯一索引:插入、删除、插入、再删除
单独建立1张去重表
todo
CAS(Compare And Swap):我期待的值和实际值(数据库中值)一致则进行下一步 *** 作
#1.首先客户端先请求服务端,先查询出当前的version版本,在update语句where条件中使用
SELECT version FROM tableName WHERE condition;
#2.根据version版本来做sql *** 作
UPDATE tableName SET fieldName version=(version+1) WHERE id=1 AND version=expectedVersion;
乐观锁CAS/状态机
有状态字段才能使用状态机
支付订单的状态:待付款(padding),锁定(locked),已付款(paid)等等
update `order` set status='locked' where id=1 and status='padding';
悲观锁+双重检查
步骤:加锁之前检查1次,加锁之后检查一次
加行锁:
- mysql需要使用innoDB引擎
- id必须是主键或者唯一索引,否则会锁表
select * from tableName id=1 for update;
缺点:事务中锁住表行,其他不需要使用此事务但需要使用被锁表行的 *** 作也将等待
分布式锁作用:分布式系统线程间的同步
将多线程并发下锁机制引入了分布式系统
使用redis或zookeeper存储分布式锁
需要同步执行的 *** 作需要先获取这个锁, *** 作执行完成后,再释放这把锁
作用:过滤setnx设置时间内的重复请求
步骤:
- 客户端请求服务端获取全局唯一token
- 客户端业务请求带上唯一token
- 服务端使用请求中的唯一token
setnx key expireTime token
,设置成功,则执行业务代码;设置失败,则返回
setnx语法
# 这个键不存在的情况下才进行设置
setnx key expireTime value
缺点:
只能保证setnx时间内没有重复请求
作用:过滤token一致的重复请求,即过滤第2步业务请求
步骤:
- 客户端请求服务端获取全局唯一token,服务端将此唯一token存储在redis中
- 客户端业务请求带上唯一token
- 服务端校验请求中的唯一token和redis中的唯一token是否匹配,匹配则执行业务代码,执行成功删除此唯一token;不匹配,则返回
缺点:不能过滤组合(包含:第1步-token获取请求,第2步-业务请求)重复请求
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)