什么是乐观锁、悲观锁?

news2024/10/22 10:42:55

什么是乐观锁、悲观锁?

乐观锁:乐观锁和悲观锁是并发控制的两种方式,用来确保在多线程或多用户访问共享资源时,数据的一致性和完整性。

悲观锁(Pessimistic Lock)

悲观锁假设并发操作会经常发生,因此在每次操作数据前,都会通过加锁的方式来避免其他线程或用户修改数据。它的名字来源于对数据被修改的“悲观”假设。悲观锁常用于数据库系统中,依靠数据库的锁机制来实现。

特点:

  • 锁定资源:在读或写数据之前,先获取锁。获取锁后,其他操作无法对该数据进行修改,直到锁释放。
  • 适用场景:适用于并发量高且数据争用严重的场景,确保每次操作数据时,不会被其他操作修改。
  • 性能开销:由于悲观锁通常会导致资源等待和阻塞,会影响系统性能,尤其在高并发场景下。

优点:

  • 能够保证数据在并发情况下的强一致性。
  • 数据修改过程中不会出现并发修改冲突。

缺点:

  • 由于锁定资源,可能会导致大量等待,尤其在高并发场景下,降低系统性能。
  • 可能会出现死锁问题,尤其在多个线程或事务相互等待的情况下。

乐观锁(Optimistic Lock)

乐观锁假设并发冲突不会频繁发生,因此在操作数据时不加锁。它通常会在数据提交或更新时检查是否有冲突,使用版本号或时间戳来判断数据是否被其他线程修改过。如果检测到冲突,则回滚操作并重新尝试。

特点:

  • 不加锁:数据在操作时不加锁,只是在提交或更新时检查数据是否被修改。
  • 适用场景:适用于读多写少的场景,并发冲突较少,且对性能要求较高。
  • 冲突检测:依靠检测机制来判断数据是否被修改,而不是通过锁住资源来避免冲突。

优点:

  • 没有加锁开销,性能相对较高,尤其在并发冲突较少时。
  • 避免了锁导致的等待和阻塞,适合读多写少的场景。

缺点:

  • 不能完全保证冲突不会发生,当检测到冲突时,可能需要回滚并重试操作。
  • 在高并发写操作场景中,可能会导致频繁的回滚和重试,影响性能。

区别

对比项悲观锁乐观锁
假设并发冲突频繁发生,必须锁定资源并发冲突很少发生,无需锁定资源
实现方式依赖数据库或系统的锁机制依赖版本号或时间戳进行冲突检测
性能在高并发场景下性能较差在并发较低时性能更优
适用场景数据争用严重、冲突频繁的场景读多写少、冲突较少的场景
开销可能引发大量锁等待,甚至死锁可能出现回滚重试的开销
数据一致性保证强一致性最终一致性,冲突时需要回滚重试

总结来说,悲观锁适合并发冲突频繁的场景,而乐观锁则更适合并发冲突较少的场景。在选择时,需要根据实际应用的读写操作频率、并发量、冲突概率等因素综合考虑。

实现

0.mp实现乐观锁:

1. 悲观锁的实现

悲观锁通常依赖于数据库的锁机制来实现。数据库提供了多种锁类型(如共享锁和排他锁),开发者可以通过显式加锁来实现悲观锁。常见的数据库(如 MySQL、Oracle)都有相应的锁机制。

在数据库中实现悲观锁

  • SQL语句:使用 SELECT ... FOR UPDATE
    悲观锁可以通过在查询时使用 FOR UPDATE 语句锁定行,防止其他事务修改该数据。

    MySQL 示例

    -- 事务开始
    BEGIN;
    
    -- 查询并锁定数据,其他事务不能修改这条记录
    SELECT * FROM users WHERE id = 1 FOR UPDATE;
    
    -- 执行更新操作
    UPDATE users SET balance = balance - 100 WHERE id = 1;
    
    -- 提交事务,释放锁
    COMMIT;
    

    在这个例子中,SELECT ... FOR UPDATE 会锁定 id=1 的记录,直到事务结束(通过 COMMITROLLBACK),其他事务在此期间无法修改这条记录。

在编程语言中实现悲观锁
编程语言可以通过锁对象来实现悲观锁,例如使用 Java 的 synchronized 关键字或者 Lock 接口。

  • Java 示例(使用 synchronized

    public class PessimisticLockExample {
        private final Object lock = new Object();
    
        public void updateResource() {
            synchronized (lock) {
                // 加锁后执行数据操作,确保只有一个线程能访问
                System.out.println("Resource is locked.");
                // 执行资源修改操作
            }
        }
    }
    

    在这里,synchronized 锁住了代码块,确保在同一时间只有一个线程能够执行 updateResource() 方法中的操作。

2. 乐观锁的实现

乐观锁依赖于版本号或时间戳来实现冲突检测,通常不锁定资源,而是在更新数据时检查是否有其他事务修改过数据。如果检测到数据已被修改,则回滚并重试。

在数据库中实现乐观锁

  • SQL 语句:基于版本号的实现
    通过在数据库表中增加一个 version 字段,每次更新时检查该字段是否与读取时相同。

    MySQL 示例

    -- 查询数据并获取版本号
    SELECT id, balance, version FROM users WHERE id = 1;
    
    -- 尝试更新时检查版本号是否一致
    UPDATE users 
    SET balance = balance - 100, version = version + 1
    WHERE id = 1 AND version = 1;
    
    -- 如果更新成功,表示没有并发修改;如果失败,说明版本号不一致,需重新获取数据并重试
    

    在这个例子中,version 是用户表中的一个字段。事务在更新数据时检查 version 是否与查询时一致。如果版本号已经被修改,则更新失败,意味着该记录已经被其他事务修改。

在编程语言中实现乐观锁
可以通过类似的方式实现,使用版本号或状态标记进行并发检查。

  • Java 示例(基于版本号的实现)

    public class OptimisticLockExample {
        private int version = 1;
    
        public boolean updateResource(int newVersion) {
            if (this.version == newVersion) {
                // 如果版本号匹配,更新资源并增加版本号
                this.version++;
                System.out.println("Update successful.");
                return true;
            } else {
                // 版本号不匹配,说明数据已被其他线程修改
                System.out.println("Version mismatch. Update failed.");
                return false;
            }
        }
    }
    

    在这个示例中,updateResource 方法会检查版本号是否与预期的一致。如果一致,更新成功;如果不一致,说明有并发冲突,需要重新获取数据。

优缺点总结

  • 悲观锁依赖于数据库的锁机制或程序中的同步机制,能够确保强一致性,适合高冲突场景,但代价是性能可能会因为锁等待和阻塞而降低。
  • 乐观锁则通过版本号或时间戳进行检测,适合冲突较少的场景,避免了锁带来的开销,但在高并发写操作时可能导致频繁重试。

根据实际业务需求的并发量和冲突频率选择合适的锁机制能够提高系统性能和可靠性。

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

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

相关文章

内卷中的营销大斗法:破局与挑战

如今,各个行业内卷严重,企业在营销领域展开了激烈的大斗法。 内卷,是指一种社会或文化模式在发展到一定阶段后,无法实现自我突破,只能在内部不断精细化、复杂化。商业领域的内卷表现为企业间在产品、服务、价格等方面…

Unity通过高德开放平台获取天气信息

一、注册高德开放平台账号&#xff0c;获取天气接口Key 1、构建自己的应用 网址&#xff1a;https://lbs.amap.com/api/webservice/guide/api/weatherinfo 最终调用api的地址形式&#xff1a; https://restapi.amap.com/v3/weather/weatherInfo?city110101&key<用户…

比瓴科技入选国家工业信息安全发展研究中心SBOM工作组首批成员单位

近日&#xff0c;由开放原子开源基金会主办&#xff0c;开源风险评估与治理技术实验室承办的2024开放原子开源生态大会软件物料清单&#xff08;SBOM&#xff09;分论坛在北京成功举办。 在会议上&#xff0c;国家工业信息安全发展研究中心&#xff08;简称“中心”&#xff0…

Florence-2视觉语言模型简明教程

近年来&#xff0c;计算机视觉领域见证了基础模型的兴起&#xff0c;这些模型无需训练自定义模型即可进行图像注释。我们已经看到了用于分类的 CLIP [2]、用于对象检测的 GroundingDINO [3] 和用于分割的 SAM [4] 等模型——每个模型都在其领域表现出色。但是&#xff0c;如果我…

互动装置如何助力乡村振兴展厅板块划分,实现展示效果最大化?

在这片广袤的土地上&#xff0c;每一个乡村都承载着深厚的历史与文化&#xff0c;如今&#xff0c;随着乡村振兴战略的深入实施&#xff0c;为乡村注入了新的活力&#xff0c;乡村振兴展厅的建设&#xff0c;也成为了这一奋斗目标的有力见证和辅助工具&#xff0c;我们今天就来…

从传统到智能,从被动监控到主动预警,解锁视频安防平台EasyCVR视频监控智能化升级的关键密钥

视频监控技术从传统监控到智能化升级的过程是一个技术革新和应用场景拓展的过程。智能视频监控系统通过集成AI和机器学习算法&#xff0c;能够实现行为分析、人脸识别和异常事件检测等功能&#xff0c;提升了监控的准确性和响应速度。这些系统不仅用于传统的安全防护&#xff0…

英语语法学习框架(考研)

一、简单句 英语都是由简单句构成&#xff0c;简单句共有五种基本句型&#xff1a;①主谓&#xff1b;②主谓宾&#xff1b;③主谓宾宾补&#xff1b;④主谓宾间宾&#xff08;间接宾语&#xff09;&#xff1b;⑤主系表&#xff1b; 其中谓语是句子最重要的部分&#xff0c;谓…

渗透实战 JS文件怎么利用

1.前言 关于JS在渗透测试中的关键作用&#xff0c;想必不用过多强调&#xff0c;在互联网上也有许多从JS中找到敏感信息从而拿下关键系统的案例。大部分师傅喜欢使用findsomething之类的浏览器插件&#xff0c;也有使用诸如Unexpected.information以及APIFinder之类的Burp插件…

【Linux】【命令】diff

diff DescriptionsArgumentsExamples直接使用diff命令-u 输出格式-c 输出格式并列输出-s 和 -q 脚本示例示例1&#xff1a;目录及文件差异 Descriptions diff命令用于对比两个文件或者两个文件夹的不同之处&#xff0c;求基本语法如下所示&#xff1a; diff [OPTION]... FILES…

免费插件集-illustrator插件-Ai插件-创建外接圆

文章目录 1.介绍2.安装3.通过窗口>扩展>知了插件4.功能解释5.总结 1.介绍 本文介绍一款免费插件&#xff0c;加强illustrator使用人员工作效率&#xff0c;实现创建图形中的创建外接圆功能。首先从下载网址下载这款插件https://download.csdn.net/download/m0_67316550/…

Java消息摘要:SHA验证数据完整性、密码的加密

1、SHA 算法家族 SHA&#xff08;Secure Hash Algorithm&#xff0c;安全散列算法&#xff09;是一个密码散列函数家族&#xff0c;被美国国家安全局&#xff08;NSA&#xff09;设计&#xff0c;并由美国国家标准与技术研究院&#xff08;NIST&#xff09;发布为联邦数据处理…

无人机之自主飞行关键技术篇

无人机自主飞行指的是无人机利用先进的算法和传感器&#xff0c;实现自我导航、路径规划、环境感知和自动避障等能力。这种飞行模式大大提升了无人机的智能化水平和操作的自动化程度。 一、传感器技术 传感器是无人机实现自主飞行和数据采集的关键组件&#xff0c;主要包括&a…

sql server 行转列及列转行

图1 图2 1.行转列 &#xff08;图1->图2&#xff09; 1.方法一 (数据库通用&#xff09;&#xff0c;使用max 加case when 函数 -- 行转列 图1->图2 SELECT name,MAX(CASE WHEN subject语文 THEN score ELSE 0 END) AS "语文",MAX(CASE WHEN subject数学 …

OpenSEMBA :一个用于电磁场模拟的开源软件框架

OpenSEMBA 是一个用于电磁场模拟的开源软件框架&#xff0c;主要针对时域有限差分法&#xff08;FDTD&#xff09;和其他数值方法。以下是 OpenSEMBA 的主要特点、功能和应用领域的详细介绍&#xff1a; 主要特点 开源平台 &#xff1a; OpenSEMBA 是一个开源项目&#xff0…

2025全网最全计算机毕业设计选题推荐:计算机毕设选题指导及避坑指南√

博主介绍&#xff1a;✌全网粉丝50W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HLM…

处理文件上传和进度条的显示(进度条随文件上传进度值变化)

成品效果图&#xff1a; 解决问题&#xff1a;上传文件过大时&#xff0c;等待时间过长&#xff0c;但是进度条却不会动&#xff0c;只会在上传完成之后才会显示上传完成 上传文件的upload.component.html <nz-modal [(nzVisible)]"isVisible" [nzTitle]"文…

跨浏览器免费书签管理系统

随着互联网信息的爆炸式增长&#xff0c;如何有效管理我们日常浏览中发现的重要网页&#xff0c;成为了每个重度互联网用户的需求。一个跨平台的书签管理网站能够帮助用户在不同设备之间无缝同步和管理书签。本文将分享如何使用 Python 和 SQLite 构建一个简单、易于维护的跨平…

MySQL数据库操作——(4)

目录 8 视图 8.1 常见的数据库对象 8.2 视图概述 8.2.1 为什么使用视图&#xff1f; 8.2.2 视图的理解 8.3 创建视图 8.3.1 创建单表视图 8.3.2 创建多表联合视图 8.3.3 基于视图创建视图 8.4 查看视图 8.5 更新视图的数据 8.5.1 一般情况 8.6 修改、删除视图 8.…

基于SpringBoot+Vue景区酒店点评系统【提供源码+答辩PPT+参考文档+项目部署】

&#x1f4a5; 这两年毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的JavaWeb项目缺少创新和亮点&#xff0c;往往达不到毕业答辩的要求&#xff01; ❗如何解决这类问题&#xff1f; 让我们能够顺利通过毕业&#xff0c;我也一直在不断思考、努力、精进。通过2024年…

计算机网络基本命令

实验内容&#xff1a; 1. **ipconfig命令** - **用途**&#xff1a;显示和配置TCP/IP网络设置。 - **常用选项**&#xff1a; - ipconfig&#xff1a;显示所有网络适配器的IP地址、子网掩码、默认网关等信息。 - ipconfig /all&#xff1a;显示所有网络适配器…