接口幂等的方案

news2024/11/26 13:55:40

一、什么是幂等

幂等指多次操作产生的影响只会跟一次执行的结果相同,通俗的说:某个行为重复的执行,最终获取的结果是相同的。

二、什么是接口幂等

同一个接口,对于同一个请求,不管调用多少次,产生的最终结果都应该是一样的。
举个例子,比如账户A给账户B转账100元,最终要么成功要么失败

  • 对于成功的情况,这个请求不管再请求多少次,最终的结果:A给B只成功转入了100元,不会出现重复处理的情况
  • 对于失败的情况,这个请求不管再请求多少次,转账都是失败

即成功或者失败后,不管如何重试,结果都不会再发生变化,且不会重复进行操作。

三、接口幂等需要考虑的点

(1)如何确定是同一个请求

前端传递的请求携带一个requestId,同一个请求的requestId相同

(2)接口执行结果只有3种情况

对于幂等性的接口,执行结果可以抽象为下面3种情况

  • 0:处理中
  • 1:处理成功
  • -1:处理失败

返回给调用方的结果,只能是其中一种状态。

但是最终,接口的状态只能是成功或者失败,比如刚开始状态可能返回的是0(处理中),经过调用方多次重试以后,状态必须为终态(成功或失败)

四、接口幂等的实现方案

如下,咱们可以借助一张幂等辅助表,如下,通过这张表便可实现接口幂等通用方案

  • 幂等接口对于同一个requestId,此表都会产生一条记录
  • 此表会记录幂等接口调用的详细信息:请求id、请求的状态、请求参数json字符串、响应结果json格式字符串
  • 记录的最终状态,一定会1或者-1,对于状态为0的,经过调用方的不断重试,status会变为1或者-1
  • 当status为1或者-1后,response_json即为接口最终返回值
create table t_idempotent_call
(
    id            varchar(50) primary key comment 'id,主键',
    request_id    varchar(128) not null comment '请求id,唯一',
    status        smallint     not null default 0 comment '状态,0:处理中,1:处理成功,-1:处理失败',
    request_json  mediumtext comment '请求参数json格式',
    response_json mediumtext comment '响应数据json格式',
    version       bigint       not null default 0 comment '版本号,用于乐观锁,每次更新+1',
    create_time   datetime comment '创建时间',
    update_time   datetime comment '最后更新时间',
    unique key uq_request_id (request_id)
) comment '幂等调用辅助表';

下面来看下,通过张表如何实现接口幂等的通用方案

五、接口幂等处理的通用流程

请添加图片描述

六、案例

模拟一个转账案例

-- 幂等调用辅助表
drop table if exists t_idempotent_call;
create table t_idempotent_call
(
    id            varchar(50) primary key comment 'id,主键',
    request_id    varchar(128) not null comment '请求id,唯一',
    status        smallint     not null default 0 comment '状态,0:处理中,1:处理成功,-1:处理失败',
    request_json  mediumtext comment '请求参数json格式',
    response_json mediumtext comment '响应数据json格式',
    version       bigint       not null default 0 comment '版本号,用于乐观锁,每次更新+1',
    create_time   datetime comment '创建时间',
    update_time   datetime comment '最后更新时间',
    unique key uq_request_id (request_id)
) comment '幂等调用辅助表';


-- 创建账户表
drop table if exists t_account_lesson043;
create table t_account_lesson043
(
    id      varchar(32)    not null primary key comment '用户id',
    name    varchar(50)    not null comment '用户名',
    balance decimal(12, 2) not null comment '账户余额'
) comment '账户表';

insert ignore into t_account_lesson043 value ('1','路人1','100.00');
insert ignore into t_account_lesson043 value ('2','路人2','0.00');

七、代码实现

7.1 入参、出参

在这里插入图片描述

在这里插入图片描述

7.2 查询接口幂等辅助表是否存在记录

在这里插入图片描述

7.3 请求未处理过,首次处理该请求

在这里插入图片描述

7.4 基于MybatisPlus乐观锁插件和@Version注解实现乐观锁

@Configuration
public class MyBatisPlusConfiguration {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 分页插件
        interceptor.addInnerInterceptor(paginationInnerInterceptor());
        // 乐观锁插件
        interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor());
        return interceptor;
    }

    /**
     * 分页插件,自动识别数据库类型 https://baomidou.com/guide/interceptor-pagination.html
     */
    public PaginationInnerInterceptor paginationInnerInterceptor() {
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
        // 设置数据库类型为mysql
        paginationInnerInterceptor.setDbType(DbType.MYSQL);
        // 设置最大单页限制数量,默认 500 条,-1 不受限制
        paginationInnerInterceptor.setMaxLimit(-1L);
        return paginationInnerInterceptor;
    }

    /**
     * 乐观锁插件 https://baomidou.com/guide/interceptor-optimistic-locker.html
     */
    public OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor() {
        return new OptimisticLockerInnerInterceptor();
    }

}

在这里插入图片描述

sql本身没有携带version = #{version},但是拼接后的条件里出现了version

在这里插入图片描述

2024-09-09 08:52:19.473 DEBUG 283384 --- [nio-8080-exec-4] c.i.l.i.m.I.updateById                   : ==>  Preparing: UPDATE t_idempotent_call SET request_id=?, status=?, request_json=?, response_json=?, version=?, create_time=? WHERE id=? AND version=?
2024-09-09 08:52:19.474 DEBUG 283384 --- [nio-8080-exec-4] c.i.l.i.m.I.updateById                   : ==> Parameters: 100000001(String), 1(Integer), {"requestId":"100000001","data":{"fromAccountId":"1","toAccountId":"2","transferPrice":10}}(String), {"status":1}(String), 1(Long), 2024-09-09T08:52:19.458632400(LocalDateTime), cc98b59e4fa347dfa01db88d15b71b0f(String), 0(Long)
2024-09-09 08:52:19.474 DEBUG 283384 --- [nio-8080-exec-4] c.i.l.i.m.I.updateById                   : <==    Updates: 1

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2117764.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

除了C盘其它盘都不见了?专业数据恢复策略解析

在数字时代&#xff0c;数据几乎成为了我们生活与工作的核心。然而&#xff0c;当电脑突然遭遇“除了C盘其它盘都不见了”的困境时&#xff0c;无疑是对我们数据安全的一次重大挑战。面对这样的紧急情况&#xff0c;如何迅速、有效地恢复丢失的数据&#xff0c;成为了许多用户迫…

苹果被删视频怎么恢复?分享4个靠谱的方法

平时过年过节的时候&#xff0c;亲戚家的小孩总会拿你的手机乱点一通&#xff0c;有时可能会不小心点进手机相册里面&#xff0c;误删了相册里的视频。如果苹果用户遇到这种情况&#xff0c;那该如何恢复苹果被删视频呢&#xff1f;不要慌张&#xff0c;既然你点开了这篇文章&a…

cv::convexityDefects()详解

参考链接:详解OpenCV的函数convexHull()和函数convexityDefects(),并利用它们)做凸包(凸壳)检测及凸包(凸壳)的缺陷检测-CSDN博客 void convexityDefects( InputArray contour, InputArray convexhull, OutputArray convexityDefects ); 三个参数说明如下&#xff1a; contou…

Java ArrayList扩容机制 (源码解读)

结论&#xff1a;初始长度为10&#xff0c;若所需长度小于1.5倍原长度&#xff0c;则按照1.5倍扩容。若不够用则按照所需长度扩容。 一. 明确类内部重要变量含义 1&#xff1a;数组默认长度 2:这是一个共享的空数组实例&#xff0c;用于明确创建长度为0时的ArrayList &#xff…

钙粘蛋白CDH:肿瘤靶点研究新秀

前 言&#xff1a; 钙粘蛋白是钙依赖性细胞间粘附的重要介质&#xff0c;属于跨膜糖蛋白。钙粘蛋白在组织稳态中起重要作用&#xff0c;促进组织发育、突触粘附和上皮屏障功能。钙粘蛋白功能改变与癌症进展、血管疾病和其他病理学有关。目前多种钙粘蛋白有望成为治疗靶点&…

英伟达显卡A100定制版和原厂版什么区别为什么价格相差这么大?

环境&#xff1a; 英伟达A100显卡 问题描述&#xff1a; 英伟达显卡A100定制版和原厂版什么区别为什么价格相差这么大&#xff1f; 定制版 原本 解决方案&#xff1a; NVIDIA A100显卡的定制版和原版之间的主要区别通常在于它们的设计、用途、性能以及价格。以下是一些…

如何解决线上平台抽佣高 线下门店客流少的痛点!

目前&#xff0c;许多传统零售店铺正遭遇客源下降的难题。尽管广告推广能带来一定的客流&#xff0c;但其费用昂贵。鉴于此&#xff0c;众多零售商纷纷选择加入像美团、饿了么和抖音这样的大型在线平台&#xff0c;但这些平台的高佣金率导致了利润的大幅缩水。在这样的市场环境…

“数据守护,商业共赢” — 华企盾招商会议圆满落幕

在数字化浪潮席卷全球的今天&#xff0c;数据安全已成为企业可持续发展的基石。为了共同探讨数据防护的新策略&#xff0c;推动行业生态的健康发展&#xff0c;我司于2024年9月6日成功举办了一场以“数据守护&#xff0c;商业共赢”为主题的招商会议。此次会议汇聚了来自各行各…

本地私有化RAG知识库搭建—基于Ollama+AnythingLLM保姆级教程

一、关于RAG 1.1 简介 检索增强生成&#xff08;Retrieval-Augmented Generation&#xff0c;RAG&#xff09;是一种结合了信息检索和语言模型的技术&#xff0c;它通过从大规模的知识库中检索相关信息&#xff0c;并利用这些信息来指导语言模型生成更准确和深入的答案。这种…

UEC++学习(十七)利用SceneCaptureComponent2d进行截图

最近有个需求是需要将场景中的actor进行截图&#xff0c;并且将截图保存成png&#xff0c;png中需要将场景背景忽略掉&#xff0c;只显示特定的actor。 这里是通过SceneCapture2d组件捕捉场景后&#xff0c;将背景的alpha通道设置为0&#xff0c;实现背景透明的功能。 &#x…

2024年音频转文字软件哪家强?4 款等你来测

hello&#xff0c;今天来聊聊一个超级方便的小工具&#xff0c;它能帮你把声音直接变成文字&#xff01;想想看&#xff0c;现在谁没有几个音频文件要处理的&#xff0c;比如记笔记的声音、开会的录音、做采访的素材&#xff0c;这些都能搞定。别着急&#xff0c;我现在就给你们…

static 的作用,static 在类中使用的注意事项(定义、初始化和使用),static 全局变量和普通全局变量的异同

目录 1. static 的基本作用 2. static 在类中的使用 2.1 静态成员变量 2.2 静态成员函数 3. static 变量在全局作用域中的使用 3.1 static 全局变量 3.2 普通全局变量 4. static 局部变量 5. static 全局变量与普通全局变量的异同 static 在类中的静态成员变量和成员函…

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务&#xff0c;目标是自动识别图像中的对象类别。通过卷积神经网络&#xff08;CNN&#xff09;等…

mingw c++/qt使用grpc方法详细教程

1. RPC框架 RPC框架是什么 RPC 框架说白了就是让你可以像调用本地方法一样调用远程服务提供的方法,而不需要关心底层的通信细节。简单地说就让远程服务调用更加简单、透明。 RPC包含了客户端(Client)和服务端(Server) 业界主流的 RPC 框架整体上分为三类: 1> 支持多语…

Springboot课堂评测系统的设计与实现---附源码82642

目 录 摘要 Abstract 1 绪论 1.1 研究背景与意义 1.2 开发技术和开发特点 1.3论文结构与章节安排 2 课堂评测系统系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据增加流程 2.2.2 数据修改流程 2.2.3 数据删除流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.…

MyBatis-pulsdruid数据源

MyBatis-Plus 是 MyBatis 的增强工具&#xff0c;主要用于简化数据库操作和提升开发效率。Druid 是阿里巴巴开源的数据库连接池组件&#xff0c;提供了高效的数据库连接管理和监控功能。将这两者结合使用可以更好地管理和操作数据库。以下是 MyBatis-Plus 和 Druid 数据源的总结…

数据重删技术

目录 一、名词介绍 二、重删概述 三、重删分类 四、源端重删 一、名词介绍 指纹&#xff1a;不同数据块数据通过哈希算法所生成的唯一标识。 重删率&#xff1a;&#xff08;1 - 实际备份数据量 / 已完成数据量&#xff09;* 100%。 重删卷&#xff1a;存放指纹库的物理卷。…

JAVA一键开启缘分之旅红娘相亲交友系统小程序源码

一键开启缘分之旅 —— 红娘相亲交友系统 &#x1f496; 初遇心动&#xff0c;一键启程 在这个快节奏的时代&#xff0c;找到那个对的人似乎成了一种奢侈。但别担心&#xff0c;有了“红娘相亲交友系统”&#xff0c;你的缘分之旅只需一键即可开启&#xff01;无需复杂的注册流…

【网页播放器】播放自己喜欢的音乐

// 错误处理 window.onerror function(message, source, lineno, colno, error) {console.error("An error occurred:", message, "at", source, ":", lineno);return true; };// 检查 particlesJS 是否已定义 if (typeof particlesJS ! undefi…

【Day10-配置文件日志多线程】

配置文件 介绍 配置文件 在企业开发过程中&#xff0c;我们习惯把一些需要灵活配置的数据放在一些文本文件中&#xff0c;而不是在Java代码写死我们把这种存放程序配置信息的文件&#xff0c;统称为配置文件 Properties 是一个Map集合&#xff08;键值对集合&#xff09;&am…