什么是乐观锁、悲观锁?

什么是乐观锁、悲观锁?

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

悲观锁(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.mzph.cn/bicheng/56557.shtml

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

相关文章

【漏洞复现】SpringBlade menu/list SQL注入漏洞

》》》产品描述《《《 致远互联智能协同是一个信息窗口与工作界面,进行所有信息的分类组合和聚合推送呈现。通过面向角色化、业务化、多终端的多维信息空间设计,为不同组织提供协同门户,打破组织内信息壁垒,构建统一协同沟通的平台。 》》》漏洞描述《《《 致远互联 FE协作办公…

【PyTorch】DataLoader 设置 num_workers > 0 时,出现 CUDA with multiprocessing 相关报错

【PyTorch】DataLoader 设置 num_workers > 0 时,出现 CUDA with multiprocessing 相关报错 1 报错信息2 报错分析2.1 原因2.2 结论 3 解决方法 1 报错信息 RuntimeError: Caught RuntimeError in DataLoader worker process 0.RuntimeError: Cannot re-initial…

mac安装homebrew和git

简介 由于把自己的新mac拿来撸代码,开始环境搭建,安装各种工具和依赖,安装 git 需要先安装 homebrew,然后就遇到了 homebrew 安装失败的问题。 curl: (7) Failed to connect to raw.githubusercontent.com port 443: Connection…

基于SpringBoot+Vue+uniapp的C语言在线评测系统的详细设计和实现

详细视频演示 请联系我获取更详细的演示视频 项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念,提供了一套默认的配置,让开发者可以更专注于业务逻辑而不…

NewStarCTF2024-Week2-Web-WP

目录 1、复读机 2、你能在一秒内打出八句英文吗 3、遗失的拉链 4、谢谢皮蛋 plus 5、PangBai 过家家(2) 1、复读机 测了下存在 ssti 没什么说的 fenjing 秒了 2、你能在一秒内打出八句英文吗 每次出来的需要提交的内容都不一样 exp: …

如何从头训练大语言模型: A simple technical report

写在前面 自8月底训好自己的1.5B的LLM后,一直都没有发布一个完整的技术报告,不少小伙伴私信我催更,千呼万唤始出来。其实也没有太大动力去做,原因有三: 豁然开朗:搞定全流程之后,对LLM确实豁然…

静止的秘密

在未来的某一天,科技已经发展到了令人难以置信的地步。在这个时代,视频不再是简单的记录工具,而是成为了连接现实与虚拟世界的桥梁。在这个背景下,一位名叫陈欣的年轻女程序员,发明了一种名为“时间镜像”的技术&#…

智能去毛刺:2D视觉引导机器人如何重塑制造业未来

机器人技术已经深入到各个工业领域中,为制造业带来了前所未有的变革。其中,2D视觉引导机器人技术以其精准、高效的特点,在去毛刺工艺中发挥着越来越重要的作用。本文将为您介绍2D视觉引导机器人技术的基本原理及其在去毛刺工艺中的应用&#…

Cortex-A7:一级页表(First level address translation)描述符格式及虚拟地址(VA)到物理地址(PA)转换过程

0 参考资料 ARM Cortex-A(armV7)编程手册V4.0.pdf1 Cortex-A7:一级页表(First level address translation)描述符格式及虚拟地址(VA)到物理地址(PA)转换过程 1.1 一级页表(First l…

白银票据、黄金票据和委派攻击(内网渗透)

今日你心思不在,心思不在则气息不在,气息不在则步伐不在,步伐不在,命安在。 文章目录 kerberos协议主要角色协议工作流程 白银票据白银票据伪造条件 黄金票据黄金票据伪造条件 白银票据和黄金票据哪个危害更大委派攻击非约束性委…

界面耻辱纪念堂--可视元素04

当我们第一次注意到 Visual Basic 5.0 菜单的动画效果“特性”时,我们只能嘲笑这种特性的傻气。事实上,我们并不觉得特性本身傻气,而是微软为这个特性投资,然后将这个特性应用到他们所有的主流产品(例如,Of…

06 算法基础:算法的定义、表现形式(自然语言、伪代码、流程图)、五个特性(有穷性、确定性、可行性、输入、输出)、好算法的设计目标

目录 1 算法的定义 2 算法的三种表现形式 2.1 自然语言 2.2 伪代码 2.3 流程图 3 算法的五个特性 3.1 有穷性 3.2 确定性 3.3 可行性 3.4 输入 3.5 输出 4 好算法的设计目标 4.1 正确性 4.2 可读性 4.3 健壮性 4.4 通用性 4.5 高效率与低存储量 1 算法的定义 …

力姆泰克DMB系列伺服电动缸

力姆泰克DMB系列伺服电动缸 高精度运动,运动平稳,低噪音,高速度 向下翻动查看更多 力姆泰克DMB系列伺服电动缸采用瑞士先进的伺服缸结构设计和进口散件国内组装, 保证力姆泰克伺服电动缸在国内的领先地位. 轧制滚珠丝杠保证伺服…

Google Ads API v18 发布,开发者迎来全新功能与优化

Google 发布了 Google Ads API 第 18 版,为开发者引入了多项新功能和改进。 Google 发布的 Google Ads API 第 18 版引入了增强的工具和功能,使广告主在广告活动优化和性能跟踪方面拥有更多控制权。 主要更新包括: 预算优化建议:新…

06-ArcGIS For JavaScript-requestAnimationFrame动画渲染

文章目录 概述setInterval()与setTimeout()requestAnimationFrame()requestAnimationFrame在ArcGIS For JavaScript的应用结果 概述 本节主要讲解与时间相关的三个方法setTimeout()、setInterval()和requestAnimationFrame(),这三个方法都属…

弹性力学试题解答答案

一、名词解释 圣维南原理:分布于弹性体上一小块面积(或体积)内的荷载所引起的物体中的应力,在离荷载作用区稍远的地方,基本上只同荷载的合力和合力矩有关;荷载的具体分布只影响荷载作用区附近的应力分布。…

基于springboot学生成绩管理系统

作者:计算机学长阿伟 开发技术:SpringBoot、SSM、Vue、MySQL、ElementUI等,“文末源码”。 系统展示 【2024最新】基于JavaSpringBootVueMySQL的,前后端分离。 开发语言:Java数据库:MySQL技术:…

CPO:隐含于CoT与ToT两者间的推理平衡

自OpenAI推出o1以来,随着reasoning scaling law的大行其道‌,很多研究者都将目光聚焦在“reasoning”之上,而在仅reasoning维度上,确实存在着非常深邃且让人着迷的可探索空间,毕竟这意味着围绕system2展开的下一轮认知…

Golang | Leetcode Golang题解之第486题预测赢家

题目: 题解: func PredictTheWinner(nums []int) bool {return total(nums, 0, len(nums) - 1, 1) > 0 }func total(nums []int, start, end int, turn int) int {if start end {return nums[start] * turn}scoreStart : nums[start] * turn total…

AI 视频工具合集

🐣个人主页 可惜已不在 🐤这篇在这个专栏AI_可惜已不在的博客-CSDN博客 🐥有用的话就留下一个三连吧😼 目录 前言: 正文: ​ 前言: AI 视频,科技与艺术的精彩融合。它借助先进的人工智能技术,为影像创…