我对悲观锁与乐观锁的一点理解

【MySQL笔记】正确的理解MySQL的乐观锁,悲观锁与MVCC 正确的理解MySQL的乐观锁,悲观锁与MVCC !首先声明,MySQL的测试环境是5.7 前提概念 数据库并发的三种场景 乐观锁和悲观锁的澄清 悲观锁 乐观锁 MVCC多版本并发控制 总结 乐观锁和悲观锁的抉择 OCC,PCC,MVCC 参考资料 前提概念 数据库并发的三种场景 数据库并发场景有三种,分别为: 读-读:不存在任何问题,也不需要并发控制 读-写:有隔离性问题,... 阅读详情

我对悲观锁与乐观锁的一点理解

序

说起到锁,我们都知道,加锁就意味这开销的加大,那什么时候需要加锁呢?

多个用户针对同一资源进行处理,此时就有可能出现并发问题。比如,常见的商城下单购物,扣减商品库存这一操作,在并发的情况下就有可能出现商品超卖的情况,而为了避免商品超卖这一情况,我们就需要考虑到在操作商品库存时加锁。

有一话来说就是:在并发的场景下,我们需要有序的更新某条记录时。

悲观锁与乐观锁到底是什么

悲观锁:

用一句开玩笑的话说就是总有刁民想害朕,总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,知道操作完成后才会释放锁。这样别人想拿这个数据就会阻塞直到它拿到锁。

传统的关系型数据库里边就用到了很多这种锁机制,比如行锁、表锁、读锁、写锁、排他锁等,都是在操作之前先上锁。在Java中synchronized和ReentrantLock等独占锁都是悲观锁机制的体现。

乐观锁

也就是说很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下,在此期间别人有没有去更新这个数据,如果别人修改了数据则放弃操作,否则执行操作。

这两种锁对又有哪些优劣呢

乐观锁

优势:

轻量级锁,避免了线程切换的开销

劣势:

  • 会有ABA问题

    如果一个变量V初次读取的时候是A值,并且在准备赋值的时候检查到它仍然是A值,那我们就能说明它的值没有被其他线程修改过了吗?很明显是不能的,因为在这段时间它的值可能被改为其他值,然后又改回A,那CAS操作就会误认为它从来没有被修改过。这个问题被称为CAS操作的 "ABA"问题。

  • 只能对单一变量加锁

  • 自旋操作导致额外开销

悲观锁

优势:

可以锁住多个变量

劣势:

重量级锁,加锁、释放锁操作会增加开销,而且操作系统层面的上下文切换和线程调度也会引起很大的开销。

一个线程持有锁会导致其他需要此锁的线程挂起。

两种锁的使用场景

从上面的介绍,我们知道两种锁各有优缺点,需要根据场景进行对应的选择。像乐观锁适用于多读写少的情况下,这样可以省去了锁的开销,加大系统的整体吞吐量。但如果是多写的情况下,经常会产生冲突,会导致上层应用不断重试,这样反而降低了性能,所以一般多写的场景下用悲观锁就比较合适。

放在现实开发中,比如说同为商城系统,也可以根据用户量的不同,业务的不同,使用不同的加锁机制。合适的就是最好的。

这两种锁怎么去实现

乐观锁的实现主要方式有两种:CAS算法和版本号机制

版本号机制

一般是在数据表中加入一个版本号字段,标识数据被修改的次数,读取数据时,需要同时读取版本号,当数据修改时,需要判断版本号跟数据库中的是否一致,一致时才更新,版本号+1。如果不一致则执行重试更新操作。

CAS算法

即compare and swap(比较与交换),是一种有名的无锁算法。无锁编程,即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被阻塞的情况下实现变量的同步,所以也叫非阻塞同步(Non-blocking Synchronization)。CAS算法涉及到三个操作数

  1. 需要读写的内存位置(V)
  2. 进行比较的预期值(A)
  3. 拟写入的新值(B)

操作逻辑如下:

如果内存位置V的值等于预期的A值,则将该位置更新为新值B,否则不进行任何操作。

许多CAS的操作是自旋的:如果操作不成功,会一直重试,直到操作成功为止。

这里引出一个新的问题,既然CAS包含了Compare和Swap两个操作,它又如何保证原子性呢?

答案是:CAS是由CPU支持的原子操作,其原子性是在硬件层面进行保证的。

悲观锁的两种实现:synchronized和数据库加锁

代码实现悲观锁:synchronized

synchronized通过对代码块加锁来保证线程安全:在同一时刻,只有一个线程可以执行代码块中的代码。

synchronized是一个重量级的操作,不仅是因为加锁需要消耗额外的资源,还因为线程状态的切换会涉及操作系统核心态和用户态的转换;

不过随着JVM对锁进行的一系列优化(如自旋锁、轻量级锁、锁粗化等),synchronized的性能表现已经越来越好。

数据库加锁

例:排他锁,select … for update

该查询语句会为改行记录加上排他锁,知道事务提交或回滚时才会释放排他锁。

在此期间,如果其他事务只能对改行记录执行查询操作。

注意:select … for update 一定要跟上where id = ? 的条件,id字段一定要是主键或者唯一索引,不然会导致锁全表。

最后

随着互联网的发展,三高架构的提出,悲观锁已经越来越少的使用到生产环境中了,尤其时是并发量比较大的业务场景。

所以对我们来说高并发环境下锁粒度把控是一门重要的学问,选择一个好的锁,在保证数据安全的情况下,可以大大提升吞吐率,进而提升性能。

一个很好的开源商城源码

Java 乐观锁与悲观锁 乐观锁与悲观锁的概念,之前有所讲解,这里用很小的篇幅进行知识的回顾,巩固;乐观锁与悲观锁的使用场景介绍,通过理解悲观锁与乐观锁不同的风格,理解什么场景下需要选择合适的锁,为本节的重点内容之一;了解乐观锁的缺点,乐观锁有自己的特定的缺陷,不同的锁都有自己的优点与缺点;了解乐观锁缺陷的解决方式,作为本节内容的重点之一;通过引入 Atomic 操作,实现乐观锁,为本节内容的核心,通过对比 synchronized 的实现,用两种锁机制实现同一个需求。 阅读详情

相关推荐

STM32F103移植NuttX实战:从零搭建最小系统到串口Shell(附完整配置文件)

本文详细介绍了在STM32F103C8T6开发板上移植NuttX实时操作系统的完整过程,包括环境搭建、BSP配置、系统时钟初始化、驱动裁剪、编译烧录及串口Shell交互。通过实战指南帮助开发者快速掌握NuttX移植技巧,解决典型问题,适用于嵌入式系统开发。

tree8的博客 292

通俗易懂讲乐观锁与悲观锁

假设线程1要使用乐观锁对id为1的数据做修改,在修改前,需要先查询数据数据版本,然后再执行其他逻辑,在执行其他逻辑的期间,该数据可能被其他线程所修改,在下边的案例中修改了对应的数据,此时线程1并不知道其他线程修改了数据,为了判断数据是否被修改,线程1在更新时在where条件中校验数据版本,如果数据被修改过,则version版本不可能为1,因此,可以通过update语句的影响行数判断数据是否被修改。悲观锁在使用时都会把公共资源进行加锁,其他线程处于阻塞状态,性能相较于乐观锁较低,综合以上,

FirstMrRight的博客 982

解密 vn.py 源码:从事件驱动到模块化设计的实战解析

本文深入解析vn.py源码,重点剖析其事件驱动机制与模块化设计。通过事件引擎、处理器字典等核心组件分析,展示如何实现低耦合高内聚的交易系统架构,并结合实战案例说明模块化设计带来的开发效率提升。文章还详细解读了Gateway抽象层、核心数据结构及设计模式应用,为量化交易开发者提供源码级实践指南。

weixin_27427619的博客 249

浅淡对乐观锁与悲观锁理解

(一)乐观锁和悲观锁的概念乐观锁悲观锁的理解是乐观锁是一种思想即具体实现是,表中有一个版本字段,第一次读的时候,获取到这个字段。处理完业务逻辑开始更新的时候,需要再次查看该字段的值是否和第一次的一样。如果一样更新,反之拒绝。之所以叫乐观,因为这个模式没有从数据库加锁。乐观锁,就是一种乐观心态的锁,每次访问数据时并不锁定数据,期待数据并没作修改,如果数据没被修改则作具体的业务应用程序上使用乐观锁:百...

大道至简 2464

从编译到调通:RK3588与FPGA的PCIe XDMA驱动实战解析

本文详细解析了在RK3588平台上为FPGA板卡编译、加载与调试PCIe XDMA驱动的完整实战流程。内容涵盖环境准备、Makefile深度定制、编译排错、驱动加载与内核日志解读、设备节点分析以及用户空间编程实战,旨在帮助开发者打通RK3588与FPGA之间的高速PCIe通信链路,实现稳定可靠的数据传输。

weixin_29304021的博客 482

四、Burpsuite工具之proxy模块详解-intercept功能

过了一个年,感觉好久都没有更新了,今天就从burpsuite的更新开始吧。前面已经说过了burpsuite的安装和proxy代理的配置,今天说一下proxy模块中非常有用的intercept功能。intercept是拦截的意思,在这里相当于拦截请求,可以实时的对请求进行拦截,然后请求参数的篡改,再把请求放通,从而达到实时修改请求的功能intercept的总体界面如下图所示其中下图红框中是可以修改请求目标的相关信息。

SmileAssassn的博客 1663

对于乐观锁和悲观锁的理解

对于乐观锁和悲观锁的理解 悲观锁(Pessimistic Lock): 定义:每次去拿数据的时候都认为别人会修改。所以每次在拿数据的时候都会上锁。这样别人想拿数据就被挡住,直到悲观锁被释放。 互斥同步:互斥同步最主要的问题就是进行线程阻塞和唤醒所带来的性能问题,因此这种同步也称为阻塞同步(Blocking Synchronization)。从处理问题的方式上说,互斥同步属于一种悲观的并发策略,总是认为只要不去做正确的同步措施(例如加锁),那就肯定会出现问题,无论共享数据是否真的会出现竞争,它都要进行加锁(这

Baro-du 294

2026 最新实战教程:AI 重构开发全流程(从需求→上线→运维)

1)做什么系统2)技术栈3)功能模块4)部署要求plaintext我要做一个:待办事项(Todo)全栈应用技术栈:前端:React + TypeScript + Tailwind后端:Node.js + Express + MongoDB部署:Docker + 本地运行(后续可上云)功能:- 增删改查任务- 任务状态切换(完成/未完成)- 简单错误处理请按企业级标准生成:架构设计 + 全部代码 + 接口文档 + 启动命令。

qq_35779316的博客 1684

乐观锁与悲观锁的区别

乐观锁与悲观锁的区别

这个人很懒,什么都没有留下。 3万+

基于STM32开发板的USB MIDI键盘实现

在本文中,我们介绍了如何使用STM32开发板和相应的软件工具来实现USB MIDI键盘。通过配置STM32CubeMX和编写相应的源代码,我们能够将STM32开发板转换为一个功能齐全的USB MIDI设备。我们将使用STM32开发板和相应的软件工具来实现这一功能,并提供相应的源代码供参考。此时,您应该可以使用STM32开发板作为USB MIDI键盘,并在按键按下时听到相应的音符。在STM32CubeMX中,选择适当的STM32型号,并启动一个新的项目。然后,将生成的可执行文件烧录到STM32开发板中。

2301_79326616的博客 1588

全志平台camera驱动开发(3)MIPI接口camera驱动开发

详细沟通: 请加video_D 目前开发过的allwinner平台: V5/V3/V3S/V40/T3/T7/A64等 开发过的mipi sensor: sony:imx317、imx477、imx274、imx258、imx286、imx307、imx385等 ov:ov2718、ov12895、ov2710等 ar: ar0238等 国产:gc1024、gc1034...

jzwjzw19900922的博客 9028

什么是乐观锁,什么是悲观锁

什么是乐观锁,什么是悲观锁 一、并发控制 当程序中可能出现并发的情况时,就需要通过一定的手段来保证在并发情况下数据的准确性,通过这种手段保证了当前用户和其他用户一起操作时,所得到的结果和他单独操作时的结果是一样的。这种手段就叫做并发控制。并发控制的目的是保证一个用户的工作不会对另一个用户的工作产生不合理的影响。 没有做好并发控制,就可能导致脏读、幻读和不可重复读等问题。 常说的并发控制,一般都和数据库管理系统(DBMS)有关。在 DBMS 中的并发控制的任务,是确保在多个事务同时存取数据库.

陈万洲的专栏 5905

基于STM32设计的水下水质检测装置(微信小程序)(205)

本项目设计了一款基于STM32微控制器为核心的水下水质检测设备,该设备具有高度集成化、智能化的特点,能够实时监测水深、温度、浊度及溶解性总固体(TDS)等关键水质参数,并通过4G网络将数据上传至腾讯云IOT物联网平台,实现远程监控和数据分析。同时,为了便于操作和移动观测,还配套开发了微信小程序,用户可通过微信小程序实时查看并控制设备的各项功能,如调整下潜深度等。

1250

什么是乐观锁,什么是悲观锁?

在互联网公司面试中,很多小伙伴都被问到关于锁的理解。今天,我给小伙伴们来聊一聊我对锁的理解,不管我们互斥锁、自旋锁、重入锁、读写锁、行锁、表锁等等等等这些概念,我把他们都归纳为两种类型,乐观锁和悲观锁。 1、锁的定义 1)乐观锁 首先来看乐观锁,顾名思义,乐观锁就是持比较乐观态度的锁。就是在操作数据时非常乐观,认为别的线程不会同时修改数据,所以不会上锁,但是在更新的时候会判断在此期间别的线程有没有更新过这个数据。......

Tom弹架构 2万+

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

一文彻底理解乐观锁与悲观锁

通过阅读本文可以获得什么 1、什么是乐观锁? 2、乐观锁实现方式都有什么? 3、乐观锁优缺点有哪些? 4、乐观锁适用场景? 5、什么是悲观锁? 6、悲观锁实现方式有哪几种? 7、悲观锁优缺点? 8、悲观锁的适用场景? 首先,我们先看一下什么是乐观锁,在我个人理解,乐观锁可以抽象为去银行取钱,假如银行没有人排队,所以不需要取号,直接去柜台A就可以办理业务。反之悲观锁就是假如去银行取钱,每次去都好巧不巧的都有人在柜台A排队,所以此时需要取号,然后等叫号在去柜台A办理业务。(假设银行只有一个柜台A,不..

醉鱼的博客 3027

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

深入理解乐观锁与悲观锁

在数据库的锁机制中介绍过,数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性。乐观并发控制(乐观锁)和悲观并发控制(悲观锁)是并发控制主要采用的技术手段。无论是悲观锁还是乐观锁,都是人们定义出来的概念,可以认为是一种思想。其实不仅仅是关系型数据库系统中有乐观锁和悲观锁的概念,像memcache、hibernate、tai

zhangwj0101的博客 9966

乐观锁与悲观锁

乐观锁是一种并发控制的机制,其核心思想是假设多个事务之间的冲突是不太可能发生的,因此在事务处理之前不会加锁,而是在事务提交的时候再检查是否有冲突。如果发现冲突,就会回滚事务,重新尝试。 悲观锁是一种并发控制的机制,它的核心思想是在操作数据之前,悲观地认为会有并发操作的冲突,因此先进行加锁,确保每个时刻只有一个事务可以访问或修改共享资源。

qq_52645134的博客 1511

MySQL 中的乐观锁与悲观锁

乐观锁和悲观锁是 MySQL 中两种重要的并发控制机制,它们各自适用于不同的应用场景。在实际开发中,需要根据业务需求、数据读写比例以及对数据一致性的要求等因素,合理选择使用乐观锁或悲观锁,以确保数据库系统在高并发环境下能够稳定、高效地运行,同时保证数据的完整性和一致性。

weixin_69477306的博客 2887

lock是悲观锁还是乐观锁_乐观锁与悲观锁

乐观锁与悲观锁之前略有了解,没想到上次面试正好被面试官问到,感觉撞了大运哈哈......今天对这个问题来总结一下,文章如有错误之处,欢迎各位指正。首先我们来介绍一下何为乐观锁?何为悲观锁?乐观锁我们都知道,锁的出现是为了保护共享资源的独占性的,避免多个线程同时操作一个共享资源。从名字就可以看出来,乐观锁就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断在此期间别...

weixin_31874327的博客 2467

乐观锁与悲观锁:理解并发控制与实现方式

乐观锁(Optimistic Locking)和悲观锁(Pessimistic Locking)是数据库和并发编程中常用的并发控制技术,它们的核心目的都是防止数据竞争和数据不一致,但其实现方式和适用场景有所不同。乐观锁:假设多个线程或者事务不会同时修改相同的数据,因此在读取数据时不会加锁,而在提交数据更新时才会检查是否有其他线程或事务修改了数据。如果检测到数据被改变,则回滚并重试更新。悲观锁。

lssffy的博客 1361

MySQL 悲观锁与乐观锁的理解

悲观锁与乐观锁是人们定义出来的概念,你可以理解为一种思想,是处理并发资源的常用手段。 不要把他们与mysql中提供的锁机制(表锁,行锁,排他锁,共享锁)混为一谈。 一、悲观锁 顾名思义,就是对于数据的处理持悲观态度,总认为会发生并发冲突,获取和修改数据时,别人会修改数据。所以在整个数据处理过程中,需要将数据锁定。 悲观锁的实现,通常依靠数据库提供的锁机制实现,比如mysql的排他锁,select … for update来实现悲观锁。 例子:商品秒杀过程中,库存数量的减少,避免出现超卖的情况。 CREATE

weixin_46075832的博客 1799

乐观锁和悲观锁自我理解

顾名思义,就是比较悲观的锁,总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。

csdnuu123的博客 1196

小小理解悲观锁和乐观锁

Java 按照锁的实现分为乐观锁和悲观锁,乐观锁和悲观锁并不是一种真实存在的锁,而是一种设计思想,乐观锁和悲观锁对于理解 Java 多线程和数据库来说至关重要,那么本篇文章就来详细探讨一下这两种锁的概念以及实现方式。 悲观锁 悲观锁是一种悲观思想,它总认为最坏的情况可能会出现,它认为数据很可能会被其他人所修改,所以悲观锁在持有数据的时候总会把资源或者数据锁住,这样其他线程想要请求这个资源...

sinat 6395

什么是乐观锁和悲观锁

一、什么是乐观锁 乐观锁,顾名思义就是总是假设最好的情况,每次获取数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和 CAS 算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于 write_condition 机制,其实都是提供的乐观锁。在 Java 中 java.util.concurrent.atomic 包下面的原子变量类就是使用了乐观锁的一种实现方式 CAS 实现的。 二、什么是悲观锁 .

weixin_48016395的博客 6357
上一篇: 同事疯狂的类构造器,我要疯了,Builder 模式都不会么?!!
莫名+
博客等级 码龄9年 0粉丝 11原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值