如何保证接口的幂等性?

方法预览:

  1. insert前先select
  2. 加悲观锁
  3. 加乐观锁
  4. 加唯一索引
  5. 建防重表
  6. 根据状态机
  7. 加分布式锁
  8. 获取token

为什么接口要保证幂等性?

  1. 可能存在表单重复提交
  2. 防止接口重试
  3. 消费重复消息

具体方案

  1. insert前判断数据是否存在,如果数据不存在则insert,否则update
  2. 加悲观锁 update user amount = amount-100 where id=123; ------> 先加悲观锁 select * from user id =123 for update
    以上方案注意两点:
  3. mysql 引擎必须是innodb,支持事务
  4. id 必须是主键或者索引,否则锁表
  5. 悲观锁可能会导致大量的请求阻塞,影响接口性能

幂等接口和防重接口的区别?
显然幂等接口的要求要高一些,保证防重的要求下,还要返回的接口一致

  1. 乐观锁:先查select id,version from user --> update xxx,version = version+1 where id = xxx and version =?
  2. 加唯一索引 捕获异常DuplicateKeyException,MySQLIntegrityConstraintViolationException
  3. 加防重表
  4. 获取token(基于nonce的方案): 提交表单的时候,申请token--》token 返回给前端,不保存redis---》前端带着token 请求---》判断token 在 redis 是否存在,如果存在说明,重复请求,若不存在,放入redis ,然后进行后续操作
原文地址:https://www.cnblogs.com/liuyupen/p/14716939.html