
接口一次请求和多次请求的结果一致。
单机和分布式下的区别以往在单机环境下,即使接口返回因为网络问题而丢失,用户仍然可以通过查询页面来确认有无 *** 作成功,但是在分布式环境中存在调用关系,调用关系除了成功和失败还新增一种状态超时,这个时候有必要发起重试机制,而在重试的过程中,幂等性的问题就会被放大。
为什么需要幂等例如转账业务,服务A请求服务B时返回结果超时,这个时候发起重试再次请求,应该是转账一笔而不是两笔。
创建订单需要减库存,如果减库存的接口超时了,重复调用应该保证不会多减一次库存。
3. 接口超时了,到底如何处理服务B转账接口支持幂等,服务A重新发起请求即可。
服务B转账接口不支持幂等,服务A先调用服务B的查询接口,如果查询失败则发起转账流程,如果查询成功则代表已经转账成功,继续成功流程即可。
select语句是天然幂等的,无论查询多少次都不会有问题。
delete语句可以利用唯一索引的值来进行删除或逻辑删,多次请求效果一致。
insert语句需要保证幂等性。
update语句需要保证幂等性。
其中update by id是幂等的,只修改一条记录,无论多少次都是一样的。
使用乐观锁的时候应该注意以下方式是错误的,注意在where中比较verion字段是否发生变化。
update order set version = #{version} +1,status='1' where order_id='123456'
乐观锁
数据库新增version字段,version设置为自增每次都进行+1,为了避免ABA问题,当更新时查询version字段。
select order_id,version from order where order_id='123456';
update order set version = #{version} +1,status='1' where order_id='123456' and version = #{version}
悲观锁
select … for update
Mysql中的悲观锁会有性能问题,一般不会采用。
方案一 insert唯一索引将不会重复字段值的字段设置为唯一索引 UNIQUE 类型,直接执行插入,表中没有记录则插入成功,表中有记录则会提示主键异常,捕获后返回成功。
方案二 先select后insert唯一索引在insert的基础上,多增加一层防重处理,新增记录时,先去查询库中有无记录,如果有则直接返回,如果没有在执行插入。
方案三 状态字段幂等对于很多业务是有一个业务流转状态的,每个状态都有前置状态和后置状态,以及最后的结束状态。例如流程的待审批,待审批、通过、拒绝。订单的待提交,待支付,已支付,已取消。
以订单为例,已支付的状态的前置状态只能是待支付,而取消状态的前置状态只能是待支付,通过这种状态机的流转我们就可以控制请求的幂等。
在枚举中设计前置状态字段,根据变更状态和前置状态可以控制请求的幂等。
方案四 防重表唯一索引:
需求是博客点赞问题,要想防止一个人重复点赞,可以设计一张表,将博客id与用户id绑定建立唯一索引,每当用户点赞时就往表中写入一条数据,这样重复点赞的数据就无法写入。
方案五 Token机制在某些业务,需要前端先去获取Token值,将Token放在请求头中,执行创建订单时发送Token,后端将Token写入Redis中并设置一个过期时间,接口获取请求头中的Token并跟Redis中的值进行比较,如果存在则代表第一次请求,redis中删除Token,后续请求比较失败直接返回。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)