【锁住精华】MySQL锁机制全攻略:从行锁到表锁,共享锁到排他锁,悲观锁到乐观锁

MySQL有哪些锁

1、按照锁的粒度划分

行锁

是最低粒度的的锁,锁住指定行的数据,加锁的开销较大,加锁较慢,可能会出现死锁的情况,锁的竞争度会较低,并发度相对较高。但是如果where条件里的字段没有加索引,则加的行锁会自动升级为表锁,因为行锁是基于索引去进行操作的,所以想要加行锁,就一定要在条件字段为索引的基础上进行操作。

表锁

锁住指定的表,粒度较大,但是加锁的开销小,加锁快,不会出现死锁,且锁的竞争度会较为激烈,并发度比行锁要低很多。

全局锁

粒度最大的锁,会锁住整个库,所有的表都不能进行更新插入操作,只能读。

全局锁命令如下:

flush tables with read lock;

页锁(仅了解即可,几乎用不到)

是仅在BDB(Blackhole黑洞)引擎上所支持的一种锁。页锁就是在数据页上,以页为维度进行锁定的,一页里面会有多行数据。页锁的开销是介于行锁和表锁之间的,并发度一般。

2、按照互斥性划分

共享锁(读锁)

一个事务给某行数据加上共享锁之后,其他事务就不能再加拍排他锁,但是可以加共享锁。因为读操作不会去改变数据信息,所以可以允许多个事务去共享同一个共享锁,并行去读取数据,而不会互相影响。

排他锁(写锁)

一个事务给某行数据加上排他锁之后,其他事务就不能再给这行数据加任何锁,即不允许写,也不允许读。所以排他锁可以确保在同一时刻,一个被加上锁的资源只会有一个事务去进行更新操作,有效避免了多个事务同时对一条数据进行修改,导致最终出现数据不一致问题。

3、按照性能划分

注意:乐观锁、悲观锁、意向锁都不是mysql里实际上真正的锁,而是由开发人员定义出来区分两种类型锁的设计思想。

悲观锁(PCC)

悲观锁(Pessimistic Concurrency Control)的思想是,持有一种很悲观消极的态度,默认为在数据资源被外部访问时,一定会出现冲突,所以在一个线程在数据处理的过程中都会持有锁资源,保证在同一时刻,只有一个线程可以访问到这个数据,具有排他性。

一般悲观锁都是直接使用mysql数据库的行锁和表锁去实现。

乐观锁(OCC)

乐观锁(Optimistic Concurrency Control)的思想是,持有一种乐观的态度,认为即使是在并发的场景下,对于数据资源的访问,也不会出现冲突,所以不会去加锁,而是在数据进行提交更新操作的时候,才会去判断此次提交是否存在冲突,如果冲突了,便在代码逻辑层面去处理冲突之后的处理方案,是直接结束本次更新操作,还是重新再去尝试更新。

例如

user表有数据id为1,balance余额为10。

现在想实现在并发的场景下,去修改余额(线程A请求,需要扣减余额3,线程B请求,需要扣减余额9),需要避免出现余额为负数。

实现方案,给user表加一个版本号字段version,每次更新数据时,数据更新行的version版本号要加1,且在执行更新操作的时候,where条件里需要带上版本号。

操作流程

请添加图片描述

详细过程解析

线程A和线程B同时获取到用户的余额为10,数据版本为1。

然后线程A先执行了更新操作,将用户的余额改成了7(线程A要扣减余额3),数据版本也变成了2。

紧接着线程B也来执行更新操作了,但是因为线程B查询用户余额时,线程A还没有更新数据,所以线程B要将用户的余额改成1(线程B要扣减余额9)。

但是在更新时,因为线程B拿到的数据版本是1,而此时的数据版本已经成为了2,所以线程B的更新操作失败了。

此时线程B接收到更新操作失败的结果后,可以选择直接抛出异常给用户,或者重新查询用户余额之后,再去尝试扣减余额操作。

意向锁(仅了解即可)

意向锁可简单理解为在操作行锁时,在表上添加了一个标识,表明这个表已经存在了共享锁或排他锁,其他事务在想加锁时,只需要到表上判断下这个标识就知道自己能否继续往下获取到锁。

深入了解可看文章 《 深度解读MySQL意向锁的工作原理机制与应用场景 》

间隙锁(Gap-Lock)

间隙锁是InnoDB在可重复读的隔离级别下,为了解决幻读而引入的一种锁机制。

间隙锁只会在数据表的隔离级别为可重复读隔离级别下才能生效。

是在索引记录之间的间隙上加的一个锁,是锁定了一个数据区间,比如一数据表的字段a数据为[1, 2, 5, 9],如果sql如下

select * from tablename where a = 3 for update;

,则加的间隙锁就是[2, 5],间隙的范围是根据检索条件向下寻找最靠近检索条件的记录值A,用于作为左区间,向上寻找最靠近检索条件的记录值B,用于作为右区间,即锁定的间隙为(A,B)。加上了间隙锁,则[2, 5]区间的数据都不能再进行操作,直到锁释放。

4、加锁方式

查询语句加共享锁

# 如果id有索引,则是加的行级共享锁,如果id没有索引,则加的是表级共享锁
select * from tablename where id = 'xxxx' lock in share mode;

查询语句加排他锁

# 如果id有索引,则是加的行级排他锁,如果id没有索引,则加的是表级排他锁
select * from tablename where id = 'xxxx' for update

在操作delete、update、insert语句时,数据库会自动加上排他锁(如果条件有索引,则是加的行级锁,如果条件没有索引,则加的是表级锁)。

请添加图片描述

关注我,我将持续输出Java常用相关技术文章。

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

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

相关文章

Debain docker容器离线安装ping命令

已经成功下载了 iputils-ping_20180629-2deb10u2_amd64.deb 文件。接下来需要将这个 .deb 文件复制到 Docker 容器中并安装。以下是详细步骤:下载链接:https://debian.pkgs.org/10/debian-main-amd64/iputils-ping_20180629-2deb10u2_amd64.deb.html 中的…

WPF入门教学十九 属性动画与时间线

在WPF中,属性动画是通过改变对象的依赖属性值来创建动画效果的一种方式。时间线(Timeline)是控制动画播放进度的核心组件。WPF提供了多种类型的动画和时间线,包括DoubleAnimation、ColorAnimation、PointAnimation等,以…

Python | Leetcode Python题解之第432题全O(1)的数据结构

题目: 题解: class Node:def __init__(self, key"", count0):self.prev Noneself.next Noneself.keys {key}self.count countdef insert(self, node: Node) -> Node: # 在 self 后插入 nodenode.prev selfnode.next self.nextnode.…

大模型几种对齐方法DPO, SFT, RLHF理解学习

1. 背景 大模型为什么需要对齐? 首先我们要搞清楚一个问题:LLM大语言模型预训练是监督还是无监督学习? 答案是无监督学习。 在预训练阶段,大语言模型(LLM)通过无监督学习大量的文本数据,例如…

解决Android中使用jdk 9以上中的某个类(AbstractProcessor)但是无法导入的问题

前景提要 今天在使用jdk中的AbstractProcessor类的时候,怎么都找不到,网上各种搜索,加什么依赖都没用,看了下依赖确实有这个类但是就是无法正常导入 然后翻了下android.jar,发现没有这个类 疑问 但是你尝试一下发…

Linux学习之路 -- 线程 -- 条件变量与生产消费模型

前面我们已经提过线程互斥的相关概念&#xff0c;但是我们在前文的抢票逻辑中&#xff0c;我们其实很容易发现一个问题。那就是票可能被一直被一个人抢&#xff0c;这里我们就需要引入条件变量的概念。 目录 1、条件变量 <1>线程同步 <2>相关概念 <3>相…

leetcode946. 验证栈序列

给定 pushed 和 popped 两个序列&#xff0c;每个序列中的 值都不重复&#xff0c;只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作序列的结果时&#xff0c;返回 true&#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入&#xff1a;pushed [1…

YOLO格式数据集转为COCO数据集(简单粗暴)

最近需要用的coco格式的数据集&#xff0c;但是在网上找的很多 毕竟麻烦&#xff0c;简单记录一下&#xff01; 1、调整目录结构&#xff08;以GC10-DET数据集为例&#xff09; YOLO格式数据集目录结构如下&#xff1a; 简单来说就是images文件夹里面有train、val、test三个文…

rk3588s android12 自启动 C程序

首先是 拷贝 TEST程序 到android跟文件系统看看能否成功。 首先将需要 在android 系统中 启动的 TEST 程序,拷贝到虚拟机。 这个程序 然后需要拷贝到 android 的文件系统中。 我是这样做的。 改的是这个文件。 然后, 编译+烧写测试。 发现, 在android 系…

国内车市销量激增,理想成功超越BBA

文/王俣祺 导语&#xff1a;随着“金九银十”的到来&#xff0c;国内汽车市场迎来了一个充满活力的开局。乘用车市场的销量已经迎来新的突破&#xff0c;彰显出中国汽车市场的韧性和潜力。尤为引人注目的是&#xff0c;新能源汽车销量同样激增&#xff0c;成为推动市场增长的重…

字节豆包C++一面-面经总结

talk is cheap show me the code lc206&#xff1a;链表反转&#xff1a;给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 class Solution { public:ListNode* reverseList(ListNode* head) {if(headnullptr||!head->next)return head…

RHCSA认证-Linux(RHel9)-Linux入门

文章目录 概要一、创建、查看和编辑⽂本1.1 输出重定向1.2 vim编辑器1.3 shell 变量1.5 获取帮助 二、管理本地用户和组2.1 描述用户2.2 切换用户和赋权2.3 用户管理2.4 用户组管理2.5 密码策略 三、控制文件访问3.1 列出文件和文件权限3.2 更改文件权限和拥有者3.3 控制默认权…

Node.js官网无法正常访问时安装NodeJS的方法

目录 一、使用 nvm 进行安装二、通过阿里云开源镜像站进行安装 一、使用 nvm 进行安装 此时如果直接使用 nvm install 命令进行安装会报错&#xff1a; nvm install 16.14.0Could not retrieve https://nodejs.org/dist/latest/SHASUMS256.txt. Get “https://nodejs.org/dis…

STM32精确控制步进电机

目的&#xff1a;学习使用STM32电机驱动器步进电机&#xff0c;进行电机运动精确控制。 测试环境&#xff1a; MCU主控芯片STM32F103RCT6 &#xff1b;A4988步进电机驱动器模块&#xff1b; 微型2相4线步…

AMP网站如何适配提升SEO效果?

AMP网站如何适配提升SEO效果&#xff1f; 很多网站本来就有了 PC 和 M 站&#xff0c;现在多来了个 AMP&#xff0c;如何适配提升网站SEO效果呢&#xff1f;有两种适配形式&#xff1a; 1.PC AMP 这种形式比较简单&#xff0c;只需要配置好 amphtml 和 canonical 即可。关系…

电信光猫破解记录

设置桥接上网什么的都需要光猫超级管理员密码&#xff0c;记录一下自己破解电信光猫超级管理员密码的过程 1、MAC转初始密码串 记录MAC地址 MAC地址在光猫背后 生成密码串 把MAC地址中的横杠删除&#xff0c;得到一个密码串 2、windows开启 tel功能 打开控制面板 进入程序和…

论文阅读《Co-clustering for Federated Recommender System》

论文概况 本文是2024 WWW的一篇联邦推荐论文&#xff0c;提出了一个基于特定类别物品相似度来进行聚类的联邦推荐框架。 Introduction 分析了经典聚类技术KMeans在联邦推荐设置中的不足&#xff0c;提出了一种新的共聚类联邦推荐机制CoFedRec&#xff0c;该机制在每个通信回合…

堆排序算法详解:原理与Python实现

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storm…

后端回写前端日期格式化

问题 不进行格式化处理&#xff0c;就会导致传递的字符串很奇怪 解决方案 注解&#xff08;字段&#xff09; <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.2</…

【unity进阶知识1】最详细的单例模式的设计和应用,继承和不继承MonoBehaviour的单例模式,及泛型单例基类的编写

文章目录 前言一、不使用单例二、普通单例模式1、单例模式介绍实现步骤&#xff1a;单例模式分为饿汉式和懒汉式两种。 2、不继承MonoBehaviour的单例模式2.1、基本实现2.2、防止外部实例化对象2.3、最终代码 3、继承MonoBehaviour的单例模式3.1、基本实现3.2、自动创建和挂载单…