当前位置: 首页 > news >正文

[001-03-007].第26节:分布式锁迭代3->优化基于setnx命令实现的分布式锁-防锁的误删

我的博客大纲

我的后端学习大纲


1、问题分析:

1.1.问题:

  • 1.锁的超时释放,可能会释放其他服务器的锁

1.2.场景:

  • 1.如果业务逻辑的执行时间是7s。执行流程如下
    • 1.index1业务逻辑没执行完,3秒后锁被自动释放。
    • 2.index2获取到锁,执行业务逻辑,3秒后锁被自动释放。
    • 3.index3获取到锁,执行业务逻辑
    • 4.index1业务逻辑执行完成,开始调用del释放锁,这时释放的是index3的锁,导致index3的业务只执行1s就被别人释放。最终等于没锁的情况

1.3.解决方式:

  • 1.setnx获取锁时,设置指定一个的唯一值(例如:uuid);释放前获取这个值,判断是否自己的锁
    在这里插入图片描述

1.4.编码实现:

在这里插入图片描述


2.新问题改善:

2.1.新问题说明:

  • 1.上述改善后,出现的新问题就是判断与删除条件不再一个命令中,操作缺乏原子性
    在这里插入图片描述

2.2.场景:

  • 1.index1执行删除时,查询到的lock值确实和uuid相等
  • 2.index1执行删除前,lock刚好过期时间已到,被redis自动释放
  • 3.index2获取了lock
  • 4.index1执行删除,此时会把index2的lock删除

2.3.解决方案:

  • 在redis中没有一个命令可以同时做到判断 + 删除,所有只能通过其他方式实现(如LUA脚本实现)

2.4.LUA脚本解决:

  • 1.删除LUA脚本:
if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end
  • 2.代码实现:
public void deduct() {String uuid = UUID.randomUUID().toString();// 加锁setnxwhile (!this.redisTemplate.opsForValue().setIfAbsent("lock", uuid, 3, TimeUnit.SECONDS)) {// 重试:循环try {Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();}}try {// this.redisTemplate.expire("lock", 3, TimeUnit.SECONDS);// 1. 查询库存信息String stock = redisTemplate.opsForValue().get("stock").toString();// 2. 判断库存是否充足if (stock != null && stock.length() != 0) {Integer st = Integer.valueOf(stock);if (st > 0) {// 3.扣减库存redisTemplate.opsForValue().set("stock", String.valueOf(--st));}}} finally {// 先判断是否自己的锁,再解锁String script = "if redis.call('get', KEYS[1]) == ARGV[1] " +"then " +"   return redis.call('del', KEYS[1]) " +"else " +"   return 0 " +"end";this.redisTemplate.execute(new DefaultRedisScript<>(script, Boolean.class), Arrays.asList("lock"), uuid);}
}

2.5.压力测试:

在这里插入图片描述


相关文章:

[001-03-007].第26节:分布式锁迭代3->优化基于setnx命令实现的分布式锁-防锁的误删

我的博客大纲 我的后端学习大纲 1、问题分析&#xff1a; 1.1.问题&#xff1a; 1.锁的超时释放&#xff0c;可能会释放其他服务器的锁 1.2.场景&#xff1a; 1.如果业务逻辑的执行时间是7s。执行流程如下 1.index1业务逻辑没执行完&#xff0c;3秒后锁被自动释放。2.index…...

【Unity踩坑】为什么有Rigidbody的物体运行时位置会变化

先上图&#xff0c;不知你有没有注意过这个现象呢&#xff1f; 一个物体加上了Rigidbody组件&#xff0c;当勾选上Use Gravity时&#xff0c;运行后&#xff0c;这个物体的位置的值会有变化。这是为什么呢&#xff1f; 刚体由物理系统处理&#xff0c;因此它会对重力、碰撞等做…...

NGINX开启HTTP3,给web应用提个速

环境说明 linuxdockernginx版本:1.27 HTTP3/QUIC介绍 HTTP3是由IETF于2022年发布的一个标准&#xff0c;文档地址为&#xff1a;https://datatracker.ietf.org/doc/html/rfc9114 如rfc9114所述&#xff0c;http3主要基于QUIC协议实现&#xff0c;在具备高性能的同时又兼备了…...

秋招季!别浮躁!

好久没写了&#xff0c;今天兴致来了&#xff0c;众所周知我一旦想说话&#xff0c;就来这里疯狂写。 最近&#xff0c;我去了一家国企的研究院&#xff0c;听着是不是贼高大上&#xff0c;呵——这玩意儿把我分配到三级机构&#xff0c;我一个学计算机的&#xff0c;它不把我…...

Java的时间复杂度和空间复杂度和常见排序

目录 一丶时间复杂度 二丶空间复杂度 三丶Java常见排序 1. 冒泡排序&#xff08;Bubble Sort&#xff09; 2.插入排序&#xff08;Insertion Sort&#xff09; 3.希尔排序&#xff08;Shell Sort&#xff09; 4.选择排序&#xff08;Selection Sort&#xff09; 5.堆排序&am…...

Qt 学习第十天:标准对话框 页面布局

系统标准对话框 错误对话框 //错误对话框connect(createPro, &QAction::triggered, this, []{//参数1 父亲 参数2 标题 参数3 对话框内显示文本内容 。。。QMessageBox::critical(this, "报错!", "没加头文件!");}); 【运行结果】 信息对话框 co…...

体育数据API纳米足球数据API:足球数据接口文档API示例⑩

纳米体育数据的数据接口通过JSON拉流方式获取200多个国家的体育赛事实时数据或历史数据的编程接口&#xff0c;无请求次数限制&#xff0c;可按需购买&#xff0c;接口稳定高效&#xff1b; 覆盖项目包括足球、篮球、网球、电子竞技、奥运等专题、数据内容。纳米数据API2.0版本…...

[数据集][目标检测]高铁受电弓检测数据集VOC+YOLO格式1245张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;1245 标注数量(xml文件个数)&#xff1a;1245 标注数量(txt文件个数)&#xff1a;1245 标注…...

Vuex:深入理解所涉及的几个问题

你好&#xff0c;我是沐爸&#xff0c;欢迎点赞、收藏、评论和关注。 一、Vuex 是什么&#xff1f; Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态&#xff0c;并以相应的规则保证状态以一种可预测的方式发生变化。 二、Vu…...

vue原理分析(六)研究new Vue()

今天我们来分析使用new Vue() 之前研究时&#xff0c;只是说是在创建一个实例。并没有深入进行研究 在vue的源码中找下Vue的构造函数 function Vue(options) {if (!(this instanceof Vue)) {warn$2(Vue is a constructor and should be called with the new keyword);}this.…...

滑动窗口+动态规划

前言&#xff1a;分析这个题目的时候&#xff0c;就知道要这两个线段要分开&#xff0c;但是要保证得到最优解&#xff0c;那么我们在选取第二根线段的时候&#xff0c;要保证我们第一根线段是左边最优解 并且我们选的两根线段的右端点一定是我们的数组的点&#xff08;贪心思…...

vscode配置django环境并创建django项目

1、创建文件夹 创建文件夹 并在vscode打开 终端输入命令 “ python -m venv env ” 查看目录结构 2、创建项目 在终端输入 django-admin startproject 文件名(这里以myshop为例) 3、创建应用 在myshop打开终端 在终端输入 django-admin startapp 应用名 这里以app1为例…...

WebGL系列教程四(绘制彩色三角形)

目录 1 前言2 varying变量介绍3 开始绘制3.1 声明顶点着色器3.2 声明片元着色器3.3 创建顶点和颜色的缓冲区3.4 指定变量从缓冲区获取值3.5 效果3.6 varying的内涵3.7 完整代码 4 总结 1 前言 上一篇中我们介绍了如何使用缓冲区来绘制三角形&#xff0c;这一篇我们来讲讲如何给…...

通过mxGraph在ARMxy边缘计算网关上实现工业物联网

在当今的工业4.0时代&#xff0c;工业物联网&#xff08;IIoT&#xff09;已经成为制造业转型升级的关键技术之一。ARMxy边缘计算网关作为工业自动化和物联网的重要组成部分&#xff0c;能够为工厂车间提供实时的数据处理能力和智能化服务。而mxGraph作为一种流行的JavaScript库…...

GEE案例:利用sentinel-1数据进行洪水监测分析(直方图统计)

目录 简介 数据 函数 ee.Filter.calendarRange(start, end, field) Arguments: Returns: Filter updateMask(mask) Arguments: Returns: Image 代码 结果 简介 利用sentinel-1数据进行洪水监测分析 数据 COPERNICUS/S1_GRD数据是由欧洲空间局(ESA)的Copernicus项…...

QT 联合opencv 易错点

https://blog.csdn.net/qq_51699436/article/details/135777911 网上已经有大量优秀切详尽的文章来讲述QT联合opencv了&#xff0c;我把容易出错的点列出来备忘 1、在进行opencv进行编译时&#xff0c;要确认好是32位还是64位&#xff0c;因为在创建QT项目的时候QT和opencv要匹…...

例如/举例的使用方法 ,e.g., 以及etc的使用方法

e.g. 例如 for example for the sake of example such as 1 e.g. 是拉丁语 exempli gratia 的缩写意思是“举个例子&#xff0c;比如”&#xff0c;等同于for example、 for the sake of example、such as&#xff0c;使用 e.g. 的目的是用几个例子来说明前面的观点。 2 例…...

20240902-VSCode-1.19.1-部署vcpkg-win10-22h2

20240902-VSCode-1.19.1-部署vcpkg-win10-22h2 软件环境 标签:C++ VSCode mingw gcc13 vcpkg cmake分栏:C++操作系统:Windows10 x64 22h2一、安装VScode-1.19.1 请参考另一篇文章《20240717-VSCode-1.91.1-部署gcc13-C++23-win10-22h2》。 二、安装cmake 本文流程需要安…...

MySQL学习(多表操作)

基本知识 一对多 创建部门表 – 主表 create table if not exists dept(deptno varchar(20) primary key ,name varchar(20) );创建员工表 – 创建外键约束 方式1constraint emp_fk foreign key(dept_id) references dept(deptno) create table if not exists emp(eid varc…...

鸿蒙开发(NEXT/API 12)【网络连接管理】 网络篇

简介 网络连接管理提供管理网络一些基础能力&#xff0c;包括WiFi/蜂窝/Ethernet等多网络连接优先级管理、网络质量评估、订阅默认/指定网络连接状态变化、查询网络连接信息、DNS解析等功能。 说明 为了保证应用的运行效率&#xff0c;大部分API调用都是异步的&#xff0c;对…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

Python 包管理器 uv 介绍

Python 包管理器 uv 全面介绍 uv 是由 Astral&#xff08;热门工具 Ruff 的开发者&#xff09;推出的下一代高性能 Python 包管理器和构建工具&#xff0c;用 Rust 编写。它旨在解决传统工具&#xff08;如 pip、virtualenv、pip-tools&#xff09;的性能瓶颈&#xff0c;同时…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...