Mysql悲观锁和乐观锁区别

article/2025/9/13 14:50:00

1、mysql悲观锁:在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现依靠数据库提供的锁机制,每次会申请锁并加锁和解锁操作

第一步:两个终端均关闭自动提交

左边:

右边:

第二步:左边利用 select .... for update 的悲观锁语法锁住记录

select * from employee where id = 1 for update; 

第三步:右边也尝试利用 select .... for update 的悲观锁语法锁住记录

可以看到,Sql语句被挂起(被阻塞)!

提示:如果被阻塞的时间太长,会提示如下:

第四步:左边执行更新操作并提交事务

Sql语句:

  1. update employee set money = 0 + 1 where id = 1;
  2. commit;

结果:


第五步:查看右边Sql语句的变化



2、mysql乐观锁:乐观锁认为一般情况下数据不会造成冲突,所以在数据进行提交更新时才会对数据的冲突与否进行检测。如果没有冲突那就OK;如果出现冲突了,则返回错误信息并让用户决定如何去做。

数据库本身不提供支持,而是需要开发者自己来实现,通过版本号控制及时间戳控制,重试操作也需要开发自己实现

版本号控制的原理:

  • 为表中加一个 version 字段;
  • 当读取数据时,连同这个 version 字段一起读出;
  • 数据每更新一次就将此值加一;
  • 当提交更新时,判断数据库表中对应记录的当前版本号是否与之前取出来的版本号一致,如果一致则可以直接更新,如果不一致则表示是过期数据需要重试或者做其它操作(PS:这完完全全就是 CAS 的实现逻辑呀~)
     
  1. mysql> select * from t_goods;
  2. +----+--------+------+---------+
  3. | id | status | name | version |
  4. +----+--------+------+---------+
  5. | 1 | 1 | 道具 | 1 |
  6. | 2 | 2 | 装备 | 2 |
  7. +----+--------+------+---------+
  8. 2 rows in set
  1. update t_goods
  2. set status=2, version = version + 1
  3. where id=#{id} and version = #{version};

总结&对比

 悲观锁乐观锁
概念查询时直接锁住记录使得其它事务不能查询,更不能更新提交更新时检查版本或者时间戳是否符合
语法select ... for update使用 version 或者 timestamp 进行比较
实现者数据库本身开发者
适用场景并发量大并发量小
类比JavaSynchronized关键字CAS 算法

悲观锁
优点:写多读少的并发环境中使用
缺点:加锁会增加系统开销,虽然能保证数据的安全,但数据处理吞吐量低,不适合在读书写少的场合下使用

乐观锁
优点:在读多写少的并发场景下,可以避免数据库加锁的开销
缺点:在写多读少的并发场景下,即在写操作竞争激烈的情况下,会导致CAS多次重试,冲突频率过高,导致开销比悲观锁更高


参考地址:https://www.cnblogs.com/cyhbyw/p/8869855.html
https://blog.csdn.net/SnailMann/article/details/88388829


http://chatgpt.dhexx.cn/article/H3OvlQrF.shtml

相关文章

java的乐观锁和悲观锁

参考: https://www.cnblogs.com/jyroy/p/11365935.html https://www.jianshu.com/p/ae25eb3cfb5d 乐观锁和悲观锁 乐观锁和悲观锁是一种广义上的概念,体现了看待线程同步的不同角度。 乐观锁:对于并发操作产生的线程安全问题持乐观态度&…

MySQL中悲观锁和乐观区别

1、概念不同 乐观锁( Optimistic Locking): 顾名思义,对加锁持有一种乐观的态度,即先进行业务操作,不到最后一步不进行加锁,"乐观"的认为加锁一定会成功的,在最后一步更新数据的时候再进行加锁…

PyQt5 - 双QTimer实现并行输出

QTime的使用 双Qtime的实现原理 一:QTime的使用 # -*- coding: utf-8 -*-# Form implementation generated from reading ui file D:\Qt\QT-Projects\UI项目\时间实时更新.ui # # Created by: PyQt5 UI code generator 5.12.2 # # WARNING! All changes made in t…

QTimer 定时器

QTimer类为我们提供了一个即可重复触发又可单次触发的定时器。它是一个高层次的应用程序接口。要使用它,只需创建一个QTimer类对象,将它的timeout()信号连接到适当的函数上,然后调用其start()函…

QTimer使用

QTimer工作流程 程序示例 test_timee.h //继承QObject,使用信号/槽 class TestTimer: public QObject {Q_OBJECT public:TestTimer(QObject *parent nullptr);public slots:void start();void stop();void do1();private://定义timer对象QTimer m_timer; }; tes…

定时器QTimer

学习PyQt推荐大家看这本书:https://weread.qq.com/web/reader/6393267071ccfa97639f573 链接:https://pan.baidu.com/s/1ZuHxNvEYtUqzSWqytN7viw 提取码:qku8 import sys from PyQt5.QtWidgets import QApplication,QWidget from PyQt5 i…

Qt QTimer定时器

1.QTimer简介 QTimer 主要的属性是 interval,是定时中断的周期,单位毫秒。QTimer 主要的信号是 timeout(),在定时中断时发射此信号,要想在定时中断里做出响应,这就需要编写 timeout() 信号的槽函数。 2.常用API //设…

Qt定时器QTimer使用教程与代码演示

Qt提供了定时器类QTimer, 在使用时需要包含头文件 #include <QTimer>QTimer类方法介绍: void start(int msec); 开启定时器&#xff0c;定时间隔的msec毫秒void stop(); 结束定时 QTimer信号&#xff1a; void timeout(QPrivateSignal); 在链接定时器时&#xff0c;需…

【Qt】QTimer的简单使用

定义定时器对象&#xff1a;QTimer *myTimer; 动态分部内存空间&#xff1a;myTimer new QTimer(this); 启动定时器&#xff1a;myTimer->start(100); 定时器超时事件&#xff1a;QTimer::timeout() 停止定时器&#xff1a;myTimer->stop(); 等等&#xff1b; 程序实现功…

QT之QTimer详解以及结合多线程中开启定时器的示例

一 QTimer详解 QTimer类提供了重复和单次触发信号的定时器。 a.void timeout ()定时器超时后&#xff0c;这个信号被发射。 b.void start()开启定时器,它的重载函数void start(int msec),启动或重新启动一个超时时间间隔为毫秒的定时器,如果定时器正在运行&#xff0c;它将被停…

Qt 之 QTimer

作者&#xff1a; 一去、二三里 个人微信号&#xff1a; iwaleon 微信公众号&#xff1a; 高效程序员 QTimer类提供了重复和单次触发信号的定时器。 QTimer类为定时器提供了一个高级别的编程接口。很容易使用&#xff1a;首先&#xff0c;创建一个QTimer&#xff0c;连接timeo…

DEV、SIT、UAT、PET、SIM、PRD、PROD缩写介绍

按开发、测试、上线的时间线排序&#xff1a; DEV Development 研发环境 SIT System Integrate Test 系统集成测试环境&#xff08;内测&#xff09; UAT User Acceptance Test 用户验收测试环境 PET Performance Evaluation Test 性能评估测试环境&#xff08;压测&#xff0…

什么是SIT, UAT测试

2019独角兽企业重金招聘Python工程师标准>>> SIT测试 SIT(System Integration Testing)系统集成测试&#xff0c;也叫做集成测试&#xff0c;是软件测试的一个术语&#xff0c;在其中单独的软件模块被合并和作为一个组测试。它在单元测试以后和在系统测试之前。集成…

UAT测试和SIT测试的区别

区别如下&#xff1a; 1、UAT:终端用户集成测试&#xff0c;主要是要求用户参与进测试流程&#xff0c;并得到用户对软件的认可&#xff0c;鼓励用户自己进行测试设计和进行破坏性测试&#xff0c;充分暴露系统的设计和功能问题&#xff0c;显然&#xff0c;用户的认可和破坏性…

UT-FT-ST测试

单元测试(UT)、功能测试(FT)&#xff1a; 目的&#xff1a;1、尽量避免写的代码测试人员频繁的来找你其他地方又出问题了&#xff1b;2、提供的接口不可用&#xff1b;3、一个bug修复了引入了其他的bug或者其他用例变红了&#xff1b; 理解&#xff1a;在实现函数功能的时候编…

unittest教程__测试报告(6)

用例执行完成后&#xff0c;执行结果默认是输出在屏幕上&#xff0c;其实我们可以把结果输出到一个文件中&#xff0c;形成测试报告。 unittest自带的测试报告是文本形式的&#xff0c;如下代码&#xff1a; import unittestif __name__ __main__:# 识别指定目录下所有以tes…

Pytest 分组测试

有时候需要针对不同的测试环境跑不同的测试用例&#xff0c;如&#xff1a;冒烟测试、sit、uat、prd&#xff0c;所以给自动化测试用例做标记分组是很有必要的&#xff0c;pytest.mark 可以轻松实现这个功能。首先需要注册自定义标记。 通过使用pytest.mark帮助程序&#xff0…

冒烟测试回归测试UATSIT

在软件研发中&#xff0c;冒烟测试其实是微软首先提出来的一个概念&#xff0c;和微软一直提倡的每日build&#xff08;构建版本&#xff09;有很密切的联系。具体说&#xff0c;冒烟测试就是在每日build&#xff08;构建版本&#xff09;建立后&#xff0c;对系统的基本功能进…

使用GIT提交代码流程

安装步骤&#xff1a;双击Git-2.27.0-64-bit.exe安装 双击TortoiseGit-2.10.0.2-64bit.msi安装 代码提交一般有五个步骤: 1.查看目前代码的修改状态 2.查看代码修改内容 3.暂存需要提交的文件 4.提交已暂存的文件 5.同步到服务器 登陆复制仓库的地址然后复制到下图的Directory…

Git提交代码的流程

企业级项目git远程仓库一般是由master/test/dev三个分支构成&#xff0c;开发人员是在dev上做开发&#xff0c;当需要发布测试环境或者生产环境时管理员会把开发人员提交的代码合并到test或者master上。 开发人员git操作步骤&#xff1a; 1.git clone 把远程dev上的代码克隆到本…