幂等处理

作用

幂等的作用:防止重复操作导致的脏数据

  • 前端防抖
  • 接口超时重试
  • 消息重试

我们的upsert、分布式锁、乐观锁、for update、唯一索引、状态机其实都有幂等的功能,会在请求重复的时候报错。我们主要讨论在这些机制之外,用户自定义幂等键的时候的情形

维度

接口维度的幂等:幂等的控制交给下游,由下游保证自己的请求是可以幂等/不被幂等的。比如下游直接传一个md5sum(req)作为幂等键进来(其他常用的包括req里的核心参数、reqid、时间戳、消息id)

  • 幂等键一致:直接幂等。问题:下游可能传错了,不幂等的也结果被幂等,比如批量请求、同一个请求里发起多次请求等
  • 幂等键不一致:不幂等,这个不会出错

数据维度的幂等:采用数据库的uniq key+幂等键联合判断

  • uk一致,幂等键不一致:说明用户希望再次操作同一个数据实体,不幂等
  • uk不一致,幂等键一致:说明用户希望再次操作其他数据实体,不幂等
  • uk、幂等键都一致:直接幂等
  • uk、幂等建都不一致:不幂等

实现

实现方法:

  1. 方法一:令牌发放,服务端/客户端生成一个token(幂等键),给客户端用,客户端带着token前来请求,token是一次性的,用过就直接幂等
  2. 方法二:mysql的数据表里加一列幂等键,这个表一般是操作流水表,用来记操作。每次来请求的时候从流水表查幂等键存不存在,存在则直接幂等
  3. 方法三:redis里存幂等key,用setnx+幂等key+超时时间控制

其他要注意的:

  1. 如果接口要加锁,幂等判断是要被分布式锁锁住的。因为幂等的实现是要查数据库数据的话,是可能会有变化的