幂等的这几个问题没有考虑到,你恐怕是在写Bug吧!

2023-10-27

免费视频福利推荐:

2T免费学习视频,内含精选高频面试题、SSM、Spring全家桶、微服务、MySQL、MyCat、集群、分布式、高并发、中间件、Linux、网络、多线程,Jenkins、Nexus、Docker、ELK等等免费学习视频,持续更新!


往期热门文章推荐:

1、《2019年精选优秀博文都在这里了!》

2、格式化时间用了YYYY-MM-dd,元旦当天老板喊我回去改Bug!

3、39 个奇葩代码注释,看完笑哭了。。。

4、牛逼的人,都已经开始用文言文写代码了!

5、如何优雅地根治null值引起的Bug!


关于幂等处理的几种方式,不是本文所要阐述的内容,有需要的可以参考:《高并发下的接口幂等性解决方案!

一、幂等的分类

1.1、半幂等

例如:

插入一条数据,调用服务A,A服务插入数据库的时候,根据主键冲突策略,发现已经已经存在了,直接返回错误,报已经存在主键了;

这种方式,服务A幂等做的不彻底,只是保证数据不会变更,但是通过返回错误来实现,这样的话,就需要调用方先进行一次查询操作,判断数据是否存在了,如果存在则不插入,如果不存在再调用A服务插入数据了;

1.2、全幂等

相对的,如果调用的服务A,在插入数据的时候,自己先查询一下数据是否已经存在,如果存在直接返回成功,如果不存在则执行插入操作,那么调用方就就直接执行插入操作就可以了,无需自己判断数据是否已经存在了,那么接口A就是全幂等的了;

二、幂等需要关注的几个问题

以下几点并不是需要注意问题的全部,欢迎大家留言补充!

2.1、服务的调用方和服务的提供方幂等键要保证一致,唯一性,并且不变性;

这个很好理解,例如:

  • 服务的调用方以为调用方是按照用户身份证号做幂等的,但其实服务提供方是按照手机号做幂等的,这样就出现问题了;

  • 服务的提供方前段时间还是用A做幂等键的,后边却用B了,说变就变的也是不可以的;

因此,服务调用方在调用服务之前一定要确定好服务提供方幂等键的设置;

2.3、调用方不能单纯的依靠查询来做幂等

例如:用户咔咔点击了两次,两个线程执行,同时执行插入操作,两个线程都先查询,结果某一时间点查询的数据都不存在,然后就执行插入操作了,就插入了两条数据;

在这里插入图片描述
这个时候,就需要加锁处理了或者根据主键冲突策略等方式判断幂等了;

1.1、1.2中举例还是有瑕疵的,大家注意!

2.4、调用方幂等键唯一了,但是其他数据却变了,业务做好处理,具体业务具体分析

这种情况很常见,例如:服务提供方约定以手机号作为幂等键,但是服务的调用方第一次插入数据的时候,手机号是A,其他数据是B,第二次调用的时候,手机号是A,其他数据确是C,那服务提供方到底让不让你插哪?这个就需要根据具体的业务做分析了,如果业务决定,让你插,你就插,不让你插就不能插了!

2.5、幂等键跟随数据做好持久化,做到“有据可依”,禁止幂等键纯内存拼接

这个很好理解,举个例子吧:

插入一条数据,拼接了一个幂等键ABC,你如果不做持久化,数据存储不包含ABC三个字段,那么你下次如何判断数据是否已经存在哪?

2.6、消息幂等处理的几个关键

消息幂等是一个比较复杂的场景,因为消息可能存在的无序性、重复性、延迟,都增加了幂等处理的复杂性,其中重复性则是幂等的时候需要重点考虑的;

2.6.1、重复性

例如:交易系统存在下单、支付、发货行为,交易系统如果多次消费同一笔定金支付成功消息时,由于幂等问题可能导致很多问题:
在这里插入图片描述
一般,我们在发送交易消息的时候,会把 “订单的状态和订单ID” 作为消息体的一部分,然后在接收到消息的时候,根据消息的类型判断是不是下单消息,以及判断当前订单的状态是否是”用户下单“,这样在消息不重复消费的时候,是没有问题的。

如果出现上述情况,用户下单消息重复消费,在接收到用户支付消息的时候订单状态已经被修改为已支付,但是由于用户下单消息重复消费,消息体是没有变化的(状态没有发生变化),就又修改订单状态为待支付状态了,这里显然是不对的。

我们应该做:

我们应该在接收到消息的时候,根据订单ID去数据库查询一下订单此时的状态,然后根据当前的状态判断下一步的操作,并且消息处理的时候还要加锁哦!加锁的维度可以是订单ID!防止并发的时候,出现3.3.2中的情况!

因此,不要把可变值作为幂等的条件,加锁查询订单最新的状态!

2.6.2、无序性

保证消息的顺序消费是比较复杂的,并且成本也很高,一般我们可以根据不同的业务判断消息消费的顺序性的;

例如:用户下单消息=>用户支付消息,顺序的行为是这样消费的。但无序的时候,我们可能先接收到”用户支付消息“然后才会接收到”用户下单消息“。

如果你的业务在接收用户下单消息做的处理不影响主链路的话,则可以直接先处理”用户支付消息“,当在收到”用户下单消息“的时候,查询订单的状态已经变为”已支付“,则直接把消息幂等掉,返回true,结束消息的消费。

但是,如果你的”用户下单消息“有重要的逻辑,必须先消费了之后,才可以消费”用户支付消息“,那我们就需要特别注意了!根据查询出来的订单状态进行判断,判断是否已经消费了”用户下单消息“,当先接收到”用户支付消息“的时候,消息直接重发就可以了,等消费了”用户下单消息“之后,再消费”用户支付消息“。
在这里插入图片描述

2.7、定时任务幂等处理的几个关键

定时任务的幂等需要解决的主要问题就是”重复性“,和消息的重复消费问题大致相同,需要根据查询最新的状态进行业务的处理,这里不做过多说明;


往期热门文章:

1、Stack Overflow上188W+程序员都关注的问题:Java到底是值传递还是引用传递?

2、Dubbo必会的18个面试题!一网打尽!

3、可以提高千倍效率的Java代码小技巧

4、后端开发甩锅指南!

5、答应我,别再if/else走天下了可以吗?
在这里插入图片描述

【视频福利】2T免费学习视频,搜索或扫描上述二维码关注微信公众号:Java后端技术(ID: JavaITWork),和20万人一起学Java!回复:1024,即可免费获取!内含SSM、Spring全家桶、微服务、MySQL、MyCat、集群、分布式、中间件、Linux、网络、多线程,Jenkins、Nexus、Docker、ELK等等免费学习视频,持续更新!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

幂等的这几个问题没有考虑到,你恐怕是在写Bug吧! 的相关文章

随机推荐

  • lora模块通过stm32实现数据传输(按键发送指令)

    使用串口一通过正点原子提供的串口调试助手发送数据给串口三 然后再通过串口三发送到GBC x 把数据传输给lora模块 需要手动 按键 一条一条发送配置信道速率 串口1直接用的例程就不贴程序了 usart3 c include sys h i
  • 如何给我们项目中的node_modules里面的包打补丁

    背景 我们项目所依赖的一个包因为版本问题 可能在低版本的情况下 会出现报错 我们希望能patch这个错误 shopee rn nebula import reportUIError from shopee react native sdk
  • Vue项目中eslint报错“ESLint: ‘VueRouter‘ is defined but never used.(no-unused-vars)”

    问题描述 Vue项目中eslint报错 ESLint VueRouter is defined but never used no unused vars 解决方法 a 找到项目中的 eslintrc js 将其打开 b 在 rules 中
  • 正则表达式:包含邮箱和电话号码的案例格式

    正则表达式是一种强大的文本处理工具 可以通过模式匹配的方式 从文本中进行查找 替换 提取等操作 以下是一些常用的正则表达式及其用途 匹配数字 d d可以匹配任何数字 例如 0 1 2 3 4 5 6 7 8 9 可以使用 d 匹配多个数字
  • More Effective C++条款10:在constructors内阻止资源泄露

    想像你正在开发一个多媒体通信薄软件 这个软件可以放置包括人名 地址 电话号码等文字 以及一张个人相片和一段个人声音 为了简单起见 本文中假设只包含个人相片和声音 代码实现下 include
  • 【华为OD统一考试A卷

    华为OD统一考试A卷 B卷 新题库说明 2023年5月份 华为官方已经将的 2022 0223Q 1 2 3 4 统一修改为OD统一考试 A卷 和OD统一考试 B卷 你收到的链接上面会标注A卷还是B卷 请注意 根据反馈 目前大部分收到的都是
  • 安川机器人外部信号怎么接线_工业机器人十万个怎么办-不清楚机器人IO信号怎么办?...

    I O信号介绍 I O信号就是输入 IN 输出 OUT 信号 比如传送带上货物运动到某一位置 传感器检测到后发出一个信号1给机器人和传送带 传送带接收到信号后会停止 机器人接到信号就会取走货物放到指定位置 机器人在一个码盘上码好货物后 发送
  • 这是一篇很好的很详细的http具体内容解释!和MIME解释

    转载 https www cnblogs com Dev0ps p 8074972 html HTTP请求由三部分组成 分别是 请求行 消息报头 请求正文 请求行 格式 Method Request URI HTTP Version CRL
  • 【数据挖掘复习题】

    文章目录 一 单选题 共78题 二 多选题 共31题 三 判断题 共54题 一 单选题 共78题 1 2 3 4 5 6 7 8 9 10 D C A D A B D C A D 11 12 13 14 15 16 17 18 19 20
  • 如何判断数组和对象

    一 当调用 Object prototype toString call someObject 时 实际上会调用 Object prototype toString 方法 并将 this 设置为 someObject 然后返回一个字符串 表
  • 学会Python有哪些可以做的兼职?所有途径全在这里了...

    可以干的兼职有好多 主要围绕Python的应用方向来 自媒体 现在很多搞技术的都开始进入自媒体领域 比如微信公众号 知乎 B站 抖音 小红书等 这些平台上只要你有流量 你就可以通过广告 播放量 带货等方式赚钱 当然了 自媒体需要积累 如果能
  • 数模学习(模糊数学篇)——模糊识别(python实现)

    目录 一 储备知识 1 课本定义 2 通俗理解 引入小例 如何识别 二 模糊识别方法 1 最大隶属度原则 计算方法 使用方向 2 择近原则 择近度计算方法和使用方向 三 模糊识别例题 例题1 湖泊水质识别 1 指标库标准化和样品库标准化 2
  • python爬虫怎么学?浅谈python爬虫学习的10大步骤

    如今 做跨境电商与海外社媒的从业者可谓是越来越多了 若想采集海外的相关数据 基本上是离不开爬虫的 很多小白都是不太了解这一块内容的 并且网络爬虫基本上是要使用python语言的 所以这里我就来讲讲用python爬虫要怎么学 以及分为几个步骤
  • 4.mybatis 高级结果查询

    商品订单模型 一个用户可以下n个订单 一个订单只能属于一个用户 一个订单可以有多个订单详情 订单和订单详情是一对多的关系 一个订单中可以有多个商品 一个商品也可以属于多个订单 订单和商品多对多的关系 关联查询几个需要注意的细节 1 超过三个
  • 计算机管理中的用户和组里的名称和全名有什么不同

    用户名是登录使用的 全名就是一个注释 组决定了用户的权限 计算机上 System 组的权限最高 用户中 Administrators 组的权限最高 Users 组居中 Guests 组最低 根据权限的逐渐降低 用户可访问的文件 可更改的设置
  • JAVA项目:后台管理页面——显示数据库中所有信息+删除和编辑(MySQL)

    此DEMO包含以下功能 后台管理界面 删除 修改 显示数据库里所有数据 修改编辑界面 表格检验 修改数据库里的值 后台管理界面 头像为默认头像 视频暂未上传 backstageUI jsp
  • get传递数组参数

    get请求时传递的参数有一个是数组时 要做序列化处理 下面是不需要用插件就可以解决的方法 axios有一个方法 paramsSerializer 可以处理params的数组 下面举例 vue文件里请求时传的是三个参数 methods 发送请
  • MotionBuilder调整骨骼大小尺寸

    需要先选中骨骼太能调整尺寸大小
  • 交通事故致因分析

    1 挖掘背景 随着时代的发展 我们的出行变的越来越便利的同时 也带来的越发严重的交通安全事故 我国的经济高速发展 全国汽车保有量 交通道路 人口等都在不断的增加 同时道路交通安全事故也进入高发期 分析事故发生的原因 找到事故发生的内在规律
  • 幂等的这几个问题没有考虑到,你恐怕是在写Bug吧!

    免费视频福利推荐 2T免费学习视频 内含精选高频面试题 SSM Spring全家桶 微服务 MySQL MyCat 集群 分布式 高并发 中间件 Linux 网络 多线程 Jenkins Nexus Docker ELK等等免费学习视频 持