开发中是如何保证接口幂等性的?
文章目录
- 一、定义
- 二、业务场景
- 三、保证幂等性常用方法
- 方案1: insert前先select(基于mysql的分布式锁)
- 方案2:加悲观锁 select * from table where id = '1' for update(基于mysql的分布式锁)
- 方案3:加乐观锁 增加一列:version 或者timestamp(基于mysql的分布式锁)
- 方案4:建防重复表(基于mysql的分布式锁,项目开发中常用)
- 方案5:通过状态标识字段(与乐观锁性质差不多)
- 方案6:基于redis的分布式锁
- 四、小结
一、定义
接口幂等性是指用户对于同一操作发起的一次请求或者多次请求的结果都是一致的,不会因为多次点击而产生副作用。这类问题多发生于接口的:
1.insert操作
2 update操作,如果只是单纯的更新数据,例如:update user set login_num=1 where id = 1 是没有问题的,如果还有计算,比如:update user set login_num=login_num+1 where id = 1 ,这种情况下,多次请求,可能会导致数据错误。
简单来说:幂等性=多次相同请求,数据库无重复数据+多次相同请求,返回结果一样
二、业务场景
1.填写某些form表单时,保存按钮不小心快速点了2次,表中就产生了2条重复的数据,只是id不一样(解决方案:前端控制+方案1/方案6)
2.在项目接口中为了解决接口超时问题,通常会引入重试机制,第一次请求超时,被调用方没能返回结果,于是会对该请求重试几次,这样也会产生重复的数据(解决方案:方案4)
3.mq消费者在读取消息时,有时候会读取到重复的消息,处理不好,也会产生重复的数据(解决方案:方案4)
三、保证幂等性常用方法
方案1: insert前先select(基于mysql的分布式锁)
流程图如下:
方案1说明
性能不如redis分布式锁,查询条件必须走索引,否则会锁整张表
方案2:加悲观锁 select * from table where id = ‘1’ for update(基于mysql的分布式锁)
流程图如下:
方案2说明
性能不如redis分布式锁,查询条件必须走索引,否则会锁整张表,容易造成死锁
方案3:加乐观锁 增加一列:version 或者timestamp(基于mysql的分布式锁)
流程图如下:
方案3说明
SQL-1:update user set amount = amount-100,version=version+1 where id = 1 and version =1
性能不如redis分布式锁,增加了列,增加维护成本,性能高于悲观锁
方案4:建防重复表(基于mysql的分布式锁,项目开发中常用)
流程图如下:
方案4说明
性能不如redis分布式锁,加了表,增加维护成本,在项目开发中常用,推荐使用
方案5:通过状态标识字段(与乐观锁性质差不多)
流程图同乐观锁
方案5说明
比如 订单的状态有1-下单 2-已支付 3-完成 4-撤销等状态
SQL-1:update set status=3 where id = 1 and status = 2
方案6:基于redis的分布式锁
流程图如下:
方案6说明
性能最好,如果并发过高,key过期时间过短或过长,会导致redis的负担很重;小并发场景推荐使用,太高的并发需要redis集群,推荐使用
四、小结
完整的幂等性, 除了后端外,前端也需要做防重复点击设计。
开发中是如何保证接口幂等性的?相关推荐
- 如何保证接口幂等性?
文章目录 1. 为什么要保证幂等性? 2. 如何保证接口幂等性 ①:数据库唯一主键 ②:CAS乐观锁机制 - 数据版本号 ③:防重 Token 令牌 ④:请求时携带唯一序列号ID ⑤:加本地锁 或 分 ...
- 什么是接口幂等性?为什么会产生这个问题?如何保证接口幂等性?
作者:三分恶 原文链接:https://cnblogs.com/three-fighter/p/14054749.html 博主负责的项目报了一个问题,用户操作回退失效.我们的设计里,操作回退是回到操 ...
- 【接口幂等性】使用token,Redis保证接口幂等性
使用token保证接口幂等性 接口幂等性就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用. 举个最简单的例子,那就是支付,用户购买商品后支付,支付扣款成功, ...
- 什么是接口幂等性?为什么会产生接口幂等性问题?如何保证接口幂等性?
博主负责的项目报了一个问题,用户操作回退失效.我们的设计里,操作回退是回到操作前的状态.经过查看日志发现,用户之前的操作做了两次,也就是说提交操作的接口被调用了两次,导致之用户上一次的状态和这一次的状 ...
- Android 开发中调用google语音接口
最近项目开发中需求中要采用多种的输入方式,于是乎想起google的语音搜索做了一下尝试,做了一个简单的语音识别的demo,总结起来,大致的过程如下: 一.检查Androird手机上是否装上了googl ...
- API开发中就如何提高接口优雅性的理论实践
我认为一套接口应该尽量满足以下几个原则: 安全可靠,高效,易扩展. 简单明了,可读性强,没有歧义. API 风格统一,调用规则,传入参数和返回数据有统一的标准. 我们当然可以根据自己的经验,或者参考知 ...
- 开发中不可轻视的接口文档
接口文档是描述如何与软件系统中的特定接口进行交互的文档,通常包含接口的名称.描述.请求和响应的格式.参数.返回值.错误码.调用示例等信息.它是开发人员在设计和开发软件系统时必不可少的参考资料. 日常工 ...
- 直播系统开发中如何优化API接口的并发
概述 在直播系统中,API接口并发的优化是非常重要的,因为它可以提高系统的稳定性和性能.本文将介绍一些优化API接口并发的方法. 理解API接口并发 在直播系统中,API接口是用于处理客户端请求的关键 ...
- Java网页开发中model实现Serializable接口的原因
Object serialization的定义: Object serialization 允许你将实现了Serializable接口的对象转换为字节序列,这些字节序列可以被完全存储以备以后重新生成原 ...
最新文章
- ffmpeg命令 音频文件格式转换
- 路飞学城Python-Day11
- 设置mac的全局命令
- 带学生参加电赛,5个国一,2个国二!15个省奖!
- 计算机PMA,PMA通信协议分析及仿真工具
- css cursor url用法格式详解
- 最长公共子序列模板(LCS)和LICS模板
- 有人说是金山造了熊猫烧香病毒
- Git教程——临时修改 (stash)
- 1.apple 应用内购买
- 仿大众点评下拉菜单完成
- 联想y7000p电池固件下载_联想拯救者Y7000P安装双系统win10+ubuntu18.04
- Java代码编写规范总结
- 高数(数一)知识点自我归纳(思维导图)
- Win10 Outlook打不开,无法启动Microsoft Outlook。无法打开Outlook窗口。无法打开此文件夹集合。客户端操作失败
- T31项目架构选型方案
- 针对瑞萨单片机编译时空间无法全部使用问题的解决方案
- java循环求阶乘_在Java中用循环求阶乘
- 1. Java是编译型语言还是解释型语言?
- 感动:我奋斗了18年才和你坐在一起喝咖啡(转)
热门文章
- Java 实现经典扫雷游戏 Github代码
- cad编辑节点快捷键是什么_cad编辑的快捷键是什么,Auto CAD编辑的快捷键是什么?...
- Arduino 数码管和+LED灯设计 (红绿灯)
- android开发 dts、各种接口porting----不错
- JavaScriptMVC学习(一)--Steal
- 计算机网络——TCP 协议总结
- JOMESA PT49 JOMESA PT60*60 JOMESAFR60*60 JOMESA NY-47L-20 JOMESA NY-47L-50显微镜滤膜分析系统(清洁度分析)
- Discuz! X系列远程代码执行漏洞分析
- 大语言模型: 新的摩尔定律?
- 我会接受长期出差而高工资的工作