分布式锁整理

分布锁一般有以下几种实现方式:数据库方式、redis、zookeeper 。

1、数据库方式

数据库方式,一般可以使用以下三种方式来实现

1.1 基于表记录方式

创建一张表,表中某个字段设置为unique,在需要锁时,就往表中新增一条记录,新增成功表示获取锁成功,新增失败表示获取锁失败。释放锁就删除这条记录。

总结:

  • 这种锁没有失效时间,一旦释放锁失败,这条记录就会一直保存在数据库中,从而导致其他线程永远无法获取到锁。但可以启动一个定时任务定时去清理。
  • 这种锁方式,不支持阻塞。因为插入失败会直接报错,要先获取锁,需要重新再次插入。可以弄个for循环或while循环,直到成功为止。
  • 这种锁方式是不可重入的,已经获取锁的线程,再次插入也会报错。可以加入一些字段,比如线程信息,在再次获取锁时,可以先查询,如果新增的这些信息匹配,则可以获取锁。

1.2 数据库乐观锁

需要在表中新增字段,比如叫version,针对某个表中的一条数据,每次更新前,需要先将该条记录查询出来,同时对version字段值加1,然后更新时,where条件语句后带version条件,更新成功,则表示锁已被占用,更新失败,则表示锁未被占用。

总结:

  • 该方式,不依赖于数据库本身的锁机制,不会影响请求性能,并发小的时候,只会有少数请求失败。
  • 对表需要额外增加字段,增加了数据库的冗余度。当并发高时,会频繁修改version的值,从而给数据库造成压力,也会造成大量请求失败。
  • 该方式,可用于并发量不大、并且写操作不频繁的情况下。

1.2 数据库悲观锁

该方式是数据库自带的,形如select… for update. 使用悲观锁时,MySql的InnoDB引擎时,表中必须有主键或索引才能使用行级锁(for update),否则会执行表级锁。

总结:

  • 使用悲观锁,需要关闭自动提交功能
  • 悲观锁,如果使用不当,可引发死锁

2、Redis方式

网上有很多关于使用Redis来实现分布式锁的说明,无非是用到setnx命令,抑或是SET EX PX NX命令,最后用到LUA脚本,来保证原子性。获取锁失败后,需要等待或重新尝试获取锁,浪费资源。感觉都不是很合理。后来发现有个Redisson框架,也可以实现分布式锁,该方式底层也是调用LUA脚本。

Redisson提供了锁续期功能,持有锁的线程,如果在锁键过期后,还没有执行完, 自动将锁键的时间延长。

只要线程A加锁成功,就会启动一个watch dog看门狗,它是一个后台线程,会每隔10秒检查一下,如果线程A还持有锁,那么就会不断的延长锁key的生存时间。因此Redisson解决了锁过期释放,业务没执行完问题。

    @Autowiredprivate RedissonClient redissonClient;public String lock() {// 获取锁RLock lock = redissonClient.getLock("lock"); //锁键值boolean acquired = lock.tryLock(10,-1,TimeUnit.SECONDS);if (acquired) {// 获取锁成功,执行业务逻辑return "获取锁成功,执行业务逻辑...";} else {// 获取锁失败,重试return "获取锁失败,重试...";}}public String unlock() {// 释放锁RLock lock = redissonClient.getLock("lock");lock.unlock();return "释放锁成功...";}

tryLock() 方法用于尝试获取分布式锁,该方法有三个参数:

  • waitTime:等待获取锁的时间,单位为毫秒。
  • leaseTime:锁的过期时间,单位为毫秒。
  • 时间单位

waitTime 参数表示客户端最多等待多长时间来获取锁。如果在 waitTime 时间内没有获取到锁,则会返回 false。

leaseTime 参数表示锁的过期时间。如果锁在 leaseTime 时间内没有被释放,则会自动释放。如果 leaseTime 设置为 -1,则表示锁的过期时间由 renew() 方法来控制。这样,在业务逻辑执行过程中,可以定期调用 lock.renew() 方法来续期锁的过期时间。

tryLock() 方法的返回值是一个 Boolean 值,表示是否成功获取到锁。如果成功获取到锁,则返回 true。否则,返回 false

3、ZooKeeper方式

第一种方式,利用节点名称的唯一性来实现锁。加锁操作时,所有的客户端都创建同一个名字的节点,例如/tryLock/test,只有一个客户端能创建成功,可以获得锁。解锁时,只需要删除该节点即可。其余客户端再次竞争创建节点,直到所有的客户端都获得锁。

第二种方式,利用临时顺序节点实现锁。所有的客户端,都在/test-lock目录下创建临时顺序节点,如果客户端发现自身创建的节点序号是/lock目录下最小的那个节点序号,则获得锁。否则客户端监听比自己创建的节点序号小的最大的那个节点,并进入等待状态。

比如,同一时间,创建三个节点,/test-lock/01,/test-lock/02,/test-lock/03,那么创建01的客户端先获取锁,创建02的客户端监视01节点,创建03的客户端,监视02节点。当创建01的客户端完成并删除01节点时,会唤醒创建02的客户端。

总结:

  • 第一种方式,会产生惊群效应,锁释放时,剩余的客户端都会再次竞争锁,但只有一个客户端能获取锁。
  • 第二种方式,锁释放时,只有一个客户端被唤醒。
  • 当ZooKeeper宕机时,临时顺序节点会被删除,获取锁的客户端会释放锁,不会造成一直等待锁。

具体实现可以参考:https://blog.csdn.net/weixin_41203765/article/details/141459764

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

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

相关文章

【LC】303. 区域和检索 - 数组不可变

题目描述&#xff1a; 给定一个整数数组 nums&#xff0c;处理以下类型的多个查询: 计算索引 left 和 right &#xff08;包含 left 和 right&#xff09;之间的 nums 元素的和 &#xff0c;其中 left < right 实现 NumArray 类&#xff1a; NumArray(int[] nums) 使用…

第 42 章 - Go语言 设计模式

在Go语言中&#xff0c;设计模式是一种被广泛接受的解决常见问题的最佳实践。这些模式可以分为三类&#xff1a;创建型模式、结构型模式和行为型模式。下面我将结合案例以及源代码对这三种类型的设计模式进行详细讲解。 创建型模式 创建型模式主要关注对象的创建过程&#xf…

深度学习编译器

目录 深度学习编译器 深度学习编译器的原理 举例说明 深度学习编译器 在提高并行训练可编程性方面扮演着至关重要的角色,尤其是在面对大规模智能算法开发时。下面,我将简单解释深度学习编译器的原理,并通过一个例子来说明其重要性。 深度学习编译器的原理 深度学习编译…

wordpress网站首页底部栏显示网站备案信息

一、页脚文件footer.php 例如&#xff0c;wordpress主题使用的是simple-life主题&#xff0c;服务器IP为192.168.68.89,在wordpress主题文件中有个页脚文件footer.php&#xff0c;这是一个包含网站页脚代码的文件。 footer.php 路径如下&#xff1a; /www/wwwroot/192.168.68…

使用 Vite 创建 Vue3+TS 项目并整合 ElementPlus、Axios、Pinia、Less、Vue-router 等组件或插件

前言 记录一下使用 Vite 创建 Vue3TS 项目并整合 ElementPlus、Axios、Pinia、Less、Vue-router 等组件或插件。 一、使用 Vite 创建 Vue3TS 项目 1.新建一个 temp 文件夹 &#xff08;1&#xff09;在桌面新建一个 temp 文件夹&#xff0c;然后在 VS Code 中打开此文件夹&…

【sqlcipher】pc端sqflite使用过程中遇到的问题

在flutter中使用sqlcipher时 Mac上如果通过flutter带的文件管理api&#xff08;即File的delete()方法&#xff09;删除数据库文件&#xff0c;再创建同名的数据文件的话&#xff0c;必现readonly问题&#xff0c; 这里需要注意的一点是 DatabaseFactory 在Mac上直接使用全局的…

Dubbo的RPC泛化调用

目录 一、RPC泛化调用的应用场景 二、Dubbo RPC泛化调用的实现原理 三、Dubbo RPC泛化调用的实现步骤 四、示例代码 五、泛化调用怎么发现提供该接口的服务及服务的IP和端口&#xff1f; Dubbo的RPC泛化调用是一种在调用方没有服务方提供的API的情况下&#xff0c;对服务方…

使用uni-app进行开发前准备

使用uni-app进行开发&#xff0c;需要遵循一定的步骤和流程。以下是一个详细的指南&#xff0c;帮助你开始使用uni-app进行开发&#xff1a; 一、开发环境搭建 安装Node.js&#xff1a; 首先&#xff0c;从Node.js的官方网站&#xff08;https://nodejs.org/&#xff09;下载并…

ssh的隧道连接(端口映射)

SSH 隧道&#xff08;SSH tunneling&#xff09;的命令&#xff1a;用于将本地计算机的端口与远程服务器上的端口进行映射 命令&#xff1a; ssh -L 本地端口:localhost:服务器端口 -p 22 用户名服务器ip ssh: 表示使用 SSH 协议连接远程服务器。 -L 8501:localhost:8501: 这部…

AI需求条目化全面升级!支持多格式需求,打破模板限制!

AI需求条目化全面升级&#xff01;支持多格式需求&#xff0c;打破模板限制&#xff01; 一、多格兼济 标准立成 1、功能揭秘 预览未来 平台需求板块的AI需求条目化功能迎来全面升级。它支持多种需求格式&#xff0c;不再受限于模板文件&#xff0c;能够一键自动快速且灵活地生…

SSM相关面试题01

目录 1.何为Spring Bean容器?Spring Bean容器与Spring IOC 容器有什么不同吗? 2.Spring IOC 如何理解? 3.Spring DI 如何理解? 4.Spring 中基于注解如何配置对象作用域?以及如何配置延迟加载机制? 5.Spring 工厂底层构建Bean对象借助什么机制?当对象不使用了要释放…

【c++篇】:解读Set和Map的封装原理--编程中的数据结构优化秘籍

✨感谢您阅读本篇文章&#xff0c;文章内容是个人学习笔记的整理&#xff0c;如果哪里有误的话还请您指正噢✨ ✨ 个人主页&#xff1a;余辉zmh–CSDN博客 ✨ 文章所属专栏&#xff1a;c篇–CSDN博客 文章目录 前言一.set和map的初步封装1.树的节点封装修改2.Find()查找函数3.红…

机器学习实战:泰坦尼克号乘客生存率预测(数据处理+特征工程+建模预测)

项目描述 任务&#xff1a;根据训练集数据中的数据预测泰坦尼克号上哪些乘客能生存下来 数据源&#xff1a;csv文件&#xff08;train.csv&#xff09; 目标变量&#xff1a;Survived&#xff08;0-1变量&#xff09; 数据集预览&#xff1a; 1、英文描述&#xff1a; 2、…

Linux自动化部署方法(Linux Automated Deployment Method)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 本人主要分享计算机核心技…

C++软件设计模式之组合模式与其他模式的协作举例

组合模式&#xff08;Composite Pattern&#xff09;、装饰器模式&#xff08;Decorator Pattern&#xff09;、享元模式&#xff08;Flyweight Pattern&#xff09;、迭代器模式&#xff08;Iterator Pattern&#xff09;和访问者模式&#xff08;Visitor Pattern&#xff09;…

2686694 - 操作方法:MSEG - DBSQL_REDIRECT_INCONSISTENCY

2686694 - 操作方法&#xff1a;MSEG - DBSQL_REDIRECT_INCONSISTENCY SAP Note, Version: 4, 审批日期: 24.04.2023 显示更改 组件MM-IM-GF对象状态 优先级建议/附加信息对象状态 类别咨询对象状态 审批状态已发布至客户对象状态 更正0对象状态 手动活动0对象状态已成…

嵌入式 FPGA开发

目录 一、引言 二、当前嵌入式 FPGA 开发的现状 三、嵌入式 FPGA 开发的优势 四、嵌入式 FPGA 的应用领域 1. 通信系统 2. 数字信号处理 3. 视频图像处理 4. 高速接口设计 5. 人工智能 6. IC 设计与 PCB 设计类比 五、嵌入式 FPGA 未来发展趋势 六、结论 一、引言 …

工业AI质检 AI质检智能系统 尤劲恩(上海)信息科技有限公司

来的现代化工厂&#xff0c;将逐步被无人化车间取代&#xff0c;无人工厂除了产线自动化&#xff0c;其无人质检将是绕不开的话题。尤劲恩致力于帮助工业制造领域上下游工厂减员增效、提高品质效率&#xff0c;真正实现无人质检IQC/IPQC/OQC的在线质检系统。分析生产环节真实品…

Angular v19 (三):增量水合特性详解 - 什么是水合过程?有哪些应用场景?与 Qwik 相比谁更胜一筹?- 哪个技术好我就学哪个,这就是吸心大法吧

Angular在其最新版本 v19 中引入了增量水合&#xff08;Incremental Hydration&#xff09;这一特性。这一更新引发了开发者们广泛的讨论&#xff0c;特别是在优化首屏加载速度和改善用户体验方面。本文将详解水合过程的概念、增量水合的应用场景&#xff0c;以及它与类似框架如…

[STM32]从零开始的STM32 FreeRTOS移植教程

一、前言 如果能看到这个教程的话&#xff0c;说明大家已经学习嵌入式有一段时间了。还记得嵌入式在大多数时候指的是什么吗&#xff1f;是的&#xff0c;我们所说的学习嵌入式大部分时候都是在学习嵌入式操作系统。从简单的一些任务状态机再到复杂一些的RTOS&#xff0c;再到最…