什么是幂等,什么情况下需要幂等,如何实现幂等
在微服务架构下,我们在完成一个订单流程时经常遇到下面的场景:
一个订单创建接口,第一次调用超时了,然后调用方重试了一次
在订单创建时,我们需要去扣减库存,这时接口发生了超时,调用方重试了一次
当这笔订单开始支付,在支付请求发出之后,在服务端发生了扣钱操作,接口响应超时了,调用方重试了一次
一个订单状态更新接口,调用方连续发送了两个消息,一个是已创建,一个是已付款。但是你先接收到已付款,然后又接收到了已创建
在支付完成订单之后,需要发送一条短信,当一台机器接收到短信发送的消息之后,处理较慢。消息中间件又把消息投递给另外一台机器处理
以上问题,就是在单体架构转成微服务架构之后,带来的问题。当然不是说单体架构下没有这些问题,在单体架构下同样要避免重复请求。但是出现的问题要比这少得多。
为了解决以上问题,就需要保证接口的幂等性,接口的幂等性实际上就是接口可重复调用,在调用方多次调用的情况下,接口最终得到的结果是一致的。有些接口可以天然的实现幂等性,比如查询接口,对于查询来说,你查询一次和两次,对于系统来说,没有任何影响,查出的结果也是一样。
除了查询功能具有天然的幂等性之外,增加、更新、删除都要保证幂等性。那么如何来保证幂等性呢?
全局唯一ID
使用全局唯一ID是一个通用方案,可以支持插入、更新、删除业务操作。但是这个方案看起来很美但是实现起来比较麻烦,下面的方案适用于特定的场景,但是实现起来比较简单。
去重表
插入或更新
1
2
3
4
|
insert into goods_category (goods_id,category_id,create_time,update_time)
values(#{goodsId},#{categoryId},now(),now())
on DUPLICATE KEY UPDATE
update_time=now()
|
多版本控制
这种方法适合在更新的场景中,比如我们要更新商品的名字,这时我们就可以在更新的接口中增加一个版本号,来做幂等
1
|
boolean updateGoodsName(int id,String newName,int version);
|
1
|
update goods set name=#{newName},version=#{version} whereid=#{id} and version<${version}
|
状态机控制
1
|
update `order` set status=#{status} where id=#{id} and status<#{status}
|
什么是幂等,什么情况下需要幂等,如何实现幂等相关推荐
- 一个数字可以在不损失精度的情况下达到的JavaScript的最高整数值是多少?
这是由语言定义的吗? 是否有定义的最大值? 在不同的浏览器中是否有所不同? #1楼 您要用于按位运算的任何值都必须在0x80000000(-2147483648或-2 ^ 31)和0x7fffffff ...
- java biginteger转int_如何在不使用java.math.BigInteger的情况下使用Java处理非常大的数字...
我认为程序员应该已经实现了自己的bignum库,因此欢迎在这里. (当然,稍后您会发现BigInteger更好,并且可以使用它,但这是宝贵的学习经验.) (您可以在github上关注本课程的源代码.此 ...
- 计算极限的时候,什么情况下可以用等价无穷小替换
不知道大家在学习泰勒公式的时候,对泰勒公式和无穷小等价替换有没有很迷的时候,额,我有,在求极限的题目中,有的时候是可以使用无穷小等价替换,但是有的时候一用就错,但是一直都没有太纠结什么原因,一直以为是 ...
- java中如何把时间封装成类,java-如何在不使用任何不推荐使用的类的情况下将日期从一种格式转换为另一种格式的日期对象?...
java-如何在不使用任何不推荐使用的类的情况下将日期从一种格式转换为另一种格式的日期对象? 我想将date1格式的日期转换为date2格式的日期对象. SimpleDateFormat simple ...
- 进一步封装axios并调用其读取数据(吐槽~在安卓9.0以下或者IOS10.X以下手机端H5页面不支持,在这两种情况下的系统只能使用ajax或者原生js请求后台数据)
注意!!!(修改于2020年7月18日) 在安卓9.0以下或者IOS10.X以下手机端H5页面不支持,在这两种情况下的系统只能使用ajax或者原生js请求后台数据 报错截图如下 报错内容: {&quo ...
- c# .netframwork 4.0 调用 2.0时报错 混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集。...
"System.IO.FileLoadException"类型的未经处理的异常在 XXX.dll 中发生 其他信息: 混合模式程序集是针对"v2.0.50727" ...
- c#中什么情况下用(int)什么情况下用Convert.ToInt32
1.c#中什么情况下用(int)什么情况下用Convert.ToInt32 ? 比如说有一个string型的3 ,要给它转换成int型的是用(int)3 ,还是用Convert.ToInt32(3 ...
- 关于何种情况下使用DataGrid、DataList或Repeater的一些讨论
作者:Scott Mitchell [概述] WEB开发自从有了基于脚本的WEB编程技术(如ASP)以来,经历了一个漫长的过程.通过使用微软的ASP.Net技术,传统的ASP中大量的.单调乏味的.重复 ...
- nodemanager不能正常关闭_在什么情况下不能使用罗茨风机及如何正确关闭罗茨风机...
锦工风机给大家介绍一下在什么情况下不能使用罗茨风机及如何正确关闭罗茨风机在什么情况下不能使用罗茨风机: 1.机器故障 这一点其实不用说,因为你知道,设备是存在故障确实不能使用,但会有人感觉有轻微的故障 ...
最新文章
- jnotify监控linux系统,jnotify linux使用记录
- 国产最大AI开源框架再升级:一口气发布9大新产品,顺便送出亿元GPU算力
- C语言 | 基于STM32的MPU6050模块程序(主程序)
- a commit git 参数是什么意思_深入理解Git - 一切皆commit
- 两个字符串的最长公共子序列长度_程序员编程算法,解决文本相似度问题的最长公共子序列算法!...
- epoll实现socket通信
- LOB字段存放在指定表空间 清理CLOB字段及压缩CLOB空间
- unix 网络编程总结 二
- 中专学历就该被拒之门外?做Java开发改变命运难吗?
- php-有时候你会疑惑的小问题
- 2020计算机大纲,计算机专业2020考试大纲.doc
- 声笔码和声笔数码单字效率分析
- 利用urllib读取JSON,然后将JSON解析为Python对象 —— python学习笔记
- microbit python下mp3_语音 — BBC micro:bit MicroPython中文版 0.0.1 文档
- amcharts的使用介绍
- vue文件下载进度条
- “互联网+工业”下的大数据应用场景分析
- mysql导入表空间太慢_Oracle 11g统计表空间使用率很慢
- 瑞芯微RK3568对比RK3399性能解析
- Mozilla Firefox os系统构架详解