redis+token+分布式锁确保接口的幂等性
目录
1.幂等性是什么?
2.如何实现幂等性呢?
1.新增管理员,出弹窗的同时,请求后台。
2.后端根据雪花算法生成唯一标识key,以雪花数为key存到redis。并返回key给前端。
3.前端保存后端传过来的key。
4.前端输入完成信息,点击【保存】,携带key请求后端。
5.请求到达后端,验证key,根据key去redis里查,如果得不到值,说明已处理过。否则尝试获取redisson锁,然后处理业务,并删掉redis里的值。
1.幂等性是什么?
在新增和修改功能的时候,常常需要用到幂等性。
所谓的幂等性就是,即使不小心多按了几次,仍然只执行一次。常用在下单、增量修改、插入数据的时候。

效果:
在同一时间狂点鼠标“新增”,或者jmter压测并发多线程访问这个接口,也执行一次新增。

2.如何实现幂等性呢?
本次案例采用,token+redis+分布式锁:
流程如下所示:

1.新增管理员,出弹窗的同时,请求后台。
//获取唯一标识beforeAdd() {setTimeout(() => {this.dialogAdd = true;}, 500);//请求后台拿唯一标识(this.imageUrl = ""),this.$axios.get("/api/pc-zdy-sys/admin/preAddAdmin").then((res) => {if (res.data.code == 200) {this.allRoleList = res.data.data.allRoleList; //系统里所有的角色this.key = res.data.data.key; //唯一标识key}});},
2.后端根据雪花算法生成唯一标识key,以雪花数为key存到redis。并返回key给前端。
public String preAddAdmin() {//雪花id 为key存到redis 值可以无意义Long snowflakeNextId = IdUtil.getSnowflakeNextId();String key = String.valueOf(snowflakeNextId);redisTemplate.opsForValue().set(key,"唯一标识");//返回雪花idreturn key;}
3.前端保存后端传过来的key。
data() {return {key: "", //唯一标识key};},
4.前端输入完成信息,点击【保存】,携带key请求后端。
confirmAdd() {//key带到后台去,请求接口确认新增this.AddAdmin.url = this.imageUrl;this.AddAdmin.key = this.key;if(this.isAnyFieldEmpty){this.$message({message: "不能为空",type: "danger",});return;}this.$axios.post("/api/pc-zdy-sys/admin", this.AddAdmin).then((res) => {if (res.data.code == 200) {this.$message({message: "恭喜你,新增成功",type: "success",});this.dialogAdd = false;this.queryAdmin()}}).catch((error) => {this.$message({message: "新增失败",type: "danger",});});},
5.请求到达后端,验证key,根据key去redis里查,如果得不到值,说明已处理过。否则尝试获取redisson锁,然后处理业务,并删掉redis里的值。
public void addAdmin(UserDTO userDTO) {//根据key找是否有tokenString key = userDTO.getKey();if(StringUtils.isBlank(key)||ObjectUtil.isEmpty(redisTemplate.opsForValue().get(key))){//没有key或根据key找不到token直接抛异常throw new RuntimeException("新增失败");}//拿锁去处理RLock lock = redissonClient.getLock(key);boolean b = lock.tryLock();//如果拿锁失败if(!b){throw new RuntimeException("新增失败");}lock.lock();try {//admin加到用户表User user = new User();BeanUtils.copyProperties(userDTO,user);user.setStatus(1);userMapper.insert(user);//将userDTO里角色list加到角色-用户 中间表去//需要用户id 角色id集合userRoleMapper.addRoleListToUserRole(user.getId(),userDTO.getRoleList());//删掉缓存redisTemplate.delete(key);} catch (Exception e){e.printStackTrace();}finally {lock.unlock();}}
相关文章:
redis+token+分布式锁确保接口的幂等性
目录 1.幂等性是什么? 2.如何实现幂等性呢? 1.新增管理员,出弹窗的同时,请求后台。 2.后端根据雪花算法生成唯一标识key,以雪花数为key存到redis。并返回key给前端。 3.前端保存后端传过来的key。 4.前端输入完成…...
Vue模版语法
目录 接下来学习click 例题:修改背景颜色 例题:反复点击button按钮,可以不断切换背景颜色 先看以下例题是回顾vue的用法 <body><div id"box">{{myname}} - {{myage}}</div><script>var vm new Vue({el…...
新一代开源流数据湖平台Apache Paimon入门实操-上
文章目录 概述定义核心功能适用场景架构原理总体架构统一存储基本概念文件布局 部署环境准备环境部署 实战Catalog文件系统Hive Catalog 创建表创建Catalog管理表查询创建表(CTAS)创建外部表创建临时表 修改表修改表修改列修改水印 概述 定义 Apache Pa…...
ELK 企业级日志分析系统(一)
目录 一、ELK 简介 1.1 组件说明 1.2 为什么要使用ELK 1.3 完整日志系统的基本特征 1.4 ELK工作原理 二、Elasticsearch的介绍 2.1 Elasticsearch的核心: 三、Logstash 3.1 Logstash简介 四、Kibana 五、部署ELK日志分析系统 5.1 服务器配置 5.2 ELK Elasticse…...
2023-08-01力扣今日二题-Hard-DPLIS优先队列-好题
链接: 354. 俄罗斯套娃信封问题 题意: 一个信封有长宽,如果一个信封的长宽均严格大于另一个信封,那么大的这个信封可以装下小的这个信封 求最多能套娃几个信封 解: 类似普通的最长上升子序列,但是信封…...
并发 如何创建线程 多线程
进程:一个程序的执行过程 线程:一个方法就是一个线程 并发:多个线程抢夺一个资源 操作同一个对象 创建线程方法1 //创建线程方法1 继承Thread类 重写润方法 调用start开启线程 public class TestThead extends Thread{Overridepublic voi…...
亚马逊鲲鹏系统是怎么引流的?
亚马逊鲲鹏系统有三种引流方式,可设置通过亚马逊站点搜索、站外引流、直接访问产品页面进入到相关产品页面进行操作。 1、通过亚马逊站点搜索 正常的登录到我们的亚马逊主页,然后通过设置关键词及asin,最后进入你指定的产品,进行…...
第五章 Git
5-1、Git的安装 1、为什么要使用代码版本控制系统 【1】版本控制 【2】开发中存在的麻烦 2、Git和SVN的对比 【1】Git和SVN对比 (1)SVN (2)Git 3、Git下载和安装 【1】下载 【2】安装 一路下一步就好了,更换安装…...
无涯教程-Lua - 变量声明
变量的名称可以由字母,数字和下划线字符组成。它必须以字母或下划线开头,由于Lua区分大小写,因此大写和小写字母是不同的。 在Lua中,尽管无涯教程没有变量数据类型,但是根据变量的范围有三种类型。 全局变量(Global) …...
vue3学习-组件基础、深入组件
组件 基本概述 单独的 .vue文件 单文件组件(SFC)(single file component) 使用子组件 导入,无需注册,直接使用编译时,区分大小写可使用 />关闭标签 传递 props 需要再组件上声明注册 def…...
原型链污染分析
原型链污染问题 原型链原型的继承原型链污染 原型链 原型的继承 先创建一个对象,查看一下属性 const obj { prop1: 111, prop2: 222,} 这里的Object.prototype就是对象的原型。 原型里面有许多的属性,这里面的constructor是我们需要着重关注的。 除此…...
RF PCB的9条改进型建议
1.小功率的RF的PCB设计中,主要使用标准的FR4材料(绝缘特性好、材质均匀、介电常数ε=4,10%)。主要使用4层~6层板,在成本非常敏感的情况下可以使用厚度在1mm以下的双面板,要保证反面是一个完整的地层,同时由于双面板的厚度在1mm以上,使得地层和信号层之间的FR4介质较厚,…...
网络安全(黑客)自学就业
前段时间,遇到网友提问,说为什么我信息安全专业的找不到工作? 造成这个结果主要是有两大方面的原因。 第一个原因,求职者本身的学习背景问题。那这些问题就包括学历、学校学到的知识是否扎实,是否具备较强的攻防实战…...
uni-app选择器( uni-data-picker)选择任意级别
背景说明 uni-app 官方的插件市场有数据驱动选择器,可以用作多级分类的场景。引入插件后,发现做不到只选择年级,不选择班级(似乎,只能到最后子节点了)。 需求中,有可能选择的不是叶子。比如&a…...
网络入侵探测器Pi.Alert
什么是 Pi.Alert ? Pi.Alert 是 WIFI/LAN 入侵探测器。通过扫描连接到您的 WIFI/LAN 的设备,提醒您未知设备的连接。它还警告断开“始终连接”的设备。 Pi.Alert 使用了三种扫描方式 方式1:arp-scan。arp扫描系统实用程序用于使用 arp 帧搜索…...
Flask项目打包为exe(附带项目资源,静态文件)
1.在项目根目录创建my_app.spec文件,内容如下: # -*- mode: python ; coding: utf-8 -*-block_cipher Nonea Analysis([server.py], # flask入口pathex[],binaries[], datas[("E:/**/templates","/templates"),("E:/**/s…...
无代码开发(BIP旗舰版-YonBuilder)
目录 我的应用 新建领域 菜单管理 应用构建 新建应用 对象建模 新增业务对象 新增业务实体 页面建模 新增页面 编辑页面 发布管理 我的应用 角色管理 yonbuilder开发平台,提供标准服务和专业开发服务; 本篇文章只演示标准服务的可视化应用…...
誉天程序员-瀑布模型-敏捷开发模型-DevOps模型比较
文章目录 2. 项目开发-开发方式2.1. 瀑布开发模型2.2. 敏捷开发模型2.3. DevOps开发模型2.4. 区别 自增主键策略1、数据库支持主键自增自增和uuid方案优缺点 2. 项目开发-开发方式 由传统的瀑布开发模型、敏捷开发模型,一跃升级到DevOps开发运维一体化开发模型。 …...
flutter:占位视图(骨架屏、shimmer)
前言 有时候打开美团,在刚加载数据时会显示一个占位视图,如下: 那么这个是如何实现的呢?我们可以使用shimmer来开发该功能 实现 官方文档 https://pub-web.flutter-io.cn/packages/shimmer 安装 flutter pub add shimmer示例…...
【雕爷学编程】MicroPython动手做(30)——物联网之Blynk 4
知识点:什么是掌控板? 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片,支持WiFi和蓝牙双模通信,可作为物联网节点,实现物联网应用。同时掌控板上集成了OLED…...
【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...
R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...
华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...
