幂等性的实现方案

幂等性

简介

幂等性是指:无论一个操作执行多少次,产生的效果和返回的结果都是一样的

比如:

  1. 前端重复提交的数据,后台只产生对这个数据的一个反应结果;
  2. 付款请求中,即使遇到网络重发或系统BUG重发,也只应该扣除一次钱;
  3. 发送给用户的消息,相同消息之应该发送一次;
  4. 创建业务订单时,一次业务请求只能创建一个……

技术方案

(一)天生幂等的操作

  1. select在数据不变的情况下,查询一次和查询多次的结果是一样的;
  2. delete:删除一次和删除多次都是把数据删除;
  3. Redisset操作,由于是单线程的,所以也是幂等的

(二)DB唯一索引:防止插入脏数据

  • 使用唯一索引/唯一组合索引防止插入脏数据,并发新增时如果报错,则查询一次即可,数据已经存在了。
  • 如:支付宝一个用户只能有一个资金账户,存在一对一关系,那么在资金账户表中给用户ID加唯一索引,即可保证一个用户只有一个资金账户。

(三)token + Redis/JVM内存

  1. 数据提交前,先向服务申请token,存储在Redis/JVM内存中,设置过期时间
  2. 数据提交成功后,后台校验token,并删除

(四)悲观锁

MySQL U锁(本质上是X锁):select * from table where id='xxx' for update;

注意,id一定要是主键或者唯一索引,否则会锁住整个表

(五)乐观锁

版本号:update table set id=#id#, version=version + 1 where version=#version#;

乐观锁的操作最好是用主键或者唯一索引来更新,这样是行锁,否则更新会锁住整个表

(六)分布式锁

Redis分布式锁/ZooKeeper分布式锁

(七)并发不高的后台系统:select + insert

并发不高的后台系统,或者一些任务JOB,支持重复执行,简单的处理方法是:先查下关键数据判断是否已经执行过,再进行业务处理

核心高并发流程不要使用这种方法

(八)状态机幂等

设计单据相关/任务相关的业务,状态在不同情况下会发生变更,如果状态机已经处于下一个状态,来了一个上一个状态的变更,是不能够变更的。

(九)对外提供接口的API:唯一索引

对外提供接口的API会要求请求时附带:

  1. source:来源方
  2. seq:来源方序列号

source + seq在提供方系统内作为联合唯一索引,当第三方系统调用时,首先在提供方系统内查询一下,判断是否已经处理过,如果已经处理过则返回相应结果,否则执行后返回相应结果。

-------------本文结束感谢您的阅读-------------

本文标题:幂等性的实现方案

文章作者:DragonBaby308

发布时间:2019年11月06日 - 23:02

最后更新:2019年11月06日 - 23:03

原始链接:http://www.dragonbaby308.com/idempotent/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

急事可以使用右下角的DaoVoice,我绑定了微信会立即回复,否则还是推荐Valine留言喔( ఠൠఠ )ノ
0%