当前位置: 首页 > news >正文

MySQL中的锁详解

1.概念

锁是计算机协调多个进程或者线程并发访问某一资源的机制。那么如何保证数据并发访问的一致性、有效性是数据库必须解决的一个问题,锁的冲突也是影响数据库并发访问性能的一个重要因素,所以数据库中锁的应用极为重要,其复杂度也更高。

锁的分类,以锁的颗粒度为三类:

  1. 全局锁:锁定数据库中的所有表。
  2. 表级锁:每次操作锁住整张表。
  3. 行级锁:每次操作都锁到对应行的数据。

接下来就分别对这几种锁做一个解释。

 数据库锁是数据库管理系统用来管理对数据库中数据的并发访问的一种机制。锁的存在主要是为了保证数据的完整性和一致性,以及支持事务的原子性。以下是全局锁、表级锁和行级锁的详细解释:

1.  全局锁(Global Lock):

•  全局锁是一种锁定数据库中所有表的锁。当数据库处于只读模式时,通常使用全局锁。
•  在这种模式下,没有写操作被允许,只能执行读操作。这可以用于数据库的备份或维护期间,以防止数据被修改。
•  全局锁的范围是最广的,它锁定了整个数据库实例,所有试图进行写操作的事务都会被阻塞。

-- 全局锁,整个数据库处于只读状态,其他操作均阻塞
FLUSH TABLES WITH READ LOCK-- 释放全局锁
UNLOCK TABLES

2.  表级锁(Table-Level Lock):

•  表级锁是锁定数据库中特定表的锁。当一个事务对表进行写操作(如 INSERT、UPDATE、DELETE)时,通常会请求表级锁。
•  表级锁会阻止其他事务对同一张表进行写操作,但仍然允许其他事务对这张表进行读操作,这取决于锁的类型(共享锁或排他锁)。
•  表级锁的粒度比全局锁小,它只锁定涉及的特定表,其他表可以被并发访问。 

3.  行级锁(Row-Level Lock):

•  行级锁是锁定数据库表中特定行记录的锁。这种锁的粒度最细,只锁定事务操作影响到的具体行。
•  行级锁通常在执行精确的数据操作时使用,如 UPDATE 某个具体的行或 DELETE 某个具体的行。

共享锁和排他锁 

  • 共享锁(S Lock):其他事务可读,但不可写
  • 排他锁(X Lock):其他事务不能读取也不能写

 这两种行锁之间的兼容性如下:7bb394b92dc24592979e8d1fe676bdd5.png

 共享锁和共享锁可以兼容,排他锁和其它锁都不兼容。例如,事务 A 获取了一行数据的共享锁,事务 B 可以立即获得该数据行的共享锁,也就是锁兼容;但是此时事务 B 如果想获得该数据行的排他锁,则必须等待事务 A 释数据行上的共享锁,此种情况存在锁冲突。

默认情况下,数据库中的锁都可以自动获取;但是也可以手动为数据进行加锁。我们来看一个示例,首先创建一个表:

create table t(id int auto_increment primary key,c1 int,c2 int,c3 int
);
create unique index idx_t_c1 on t(c1);
create index idx_t_c2 on t(c2);insert into t(c1,c2,c3) values (1,1,1),(2,3,4),(3,6,9);

其中,id 是主键;c1 上创建了一个唯一索引;c2 上创建了一个非唯一索引;c3 上没有索引。

接下来的示例都使用 MySQL 默认的隔离级别 Repeatable Read,除非另有说明。

然后创建两个数据库连接 T1 和 T2,先在 T1 中锁定一行数据:

-- T1
mysql> begin;
Query OK, 0 rows affected (0.00 sec)mysql> select * from t where id = 1 for share;
+----+------+------+------+
| id | c1   | c2   | c3   |
+----+------+------+------+
|  1 |    1 |    1 |    1 |
+----+------+------+------+
1 row in set (0.00 sec)

我们在事务中使用select ... for share语句获得了数据行 id = 1 上的共享锁;对于 MySQL 8.0 之前的版本,可以使用select ... lock in share mode命令。

由于 InnoDB 中的自动提交 autocommit 默认设置为 ON,我们必须在事务中为数据行加锁;或者将 autocommit 设置为 OFF。

然后在 T2 中执行以下语句: 

-- T2
mysql> select * from t where id = 1 for share;
+----+------+------+------+
| id | c1   | c2   | c3   |
+----+------+------+------+
|  1 |    1 |    1 |    1 |
+----+------+------+------+
1 row in set (0.00 sec)

结果显示,在 T2 中成功获取改行数据上的共享锁。然后尝试获取排他锁:

-- T2
mysql> select * from t where id = 1 for update;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

使用select ... for update命令获取排他锁,此时该命令会一直处于等待状态并且最终超时。也就是说,共享锁和排他锁不兼容。

最后,在 T1 中提交或者回滚事务:

-- T1
mysql> commit;

 

 

 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • SLAM ORB-SLAM2(29)PnP估计姿态
  • C++ | Leetcode C++题解之第375题猜数字大小II
  • Java面试宝典-java基础07
  • 安嘉空间:智慧科技守护空间健康
  • 认知杂谈31
  • [图解]SysML和EA建模住宅安全系统-活动作为块
  • 备战英语四级每日单词分享(30个)---第十天
  • day43 | 300.最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组
  • Java 实现不改变图片尺寸,增大图片大小(kb)
  • 虚幻5|技能栏UI优化(3)——优化技能UI并实现显示背景UI,实现技能界面设计,实现技能栏的删除和添加
  • 合宙LuatOS产品规格书——Air700EAQ
  • Redis安装+常用命令合集大全+Redis Desktop Manager
  • jQuery基础——选择器的补充方法——过滤方法、查找方法
  • 【Kotlin设计模式】Kotlin实现装饰器模式
  • 【Linux】FRP:内网穿透
  • 2017-08-04 前端日报
  • css布局,左右固定中间自适应实现
  • Date型的使用
  • iOS筛选菜单、分段选择器、导航栏、悬浮窗、转场动画、启动视频等源码
  • Javascript 原型链
  • Js基础知识(四) - js运行原理与机制
  • js数组之filter
  • linux学习笔记
  • nginx 负载服务器优化
  • SpringCloud(第 039 篇)链接Mysql数据库,通过JpaRepository编写数据库访问
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • 对JS继承的一点思考
  • 计算机常识 - 收藏集 - 掘金
  • 简单数学运算程序(不定期更新)
  • 警报:线上事故之CountDownLatch的威力
  • 快速体验 Sentinel 集群限流功能,只需简单几步
  • 如何实现 font-size 的响应式
  • 微信小程序开发问题汇总
  • 《天龙八部3D》Unity技术方案揭秘
  • 你学不懂C语言,是因为不懂编写C程序的7个步骤 ...
  • ​低代码平台的核心价值与优势
  • ​第20课 在Android Native开发中加入新的C++类
  • ‌U盘闪一下就没了?‌如何有效恢复数据
  • #systemverilog# 之 event region 和 timeslot 仿真调度(十)高层次视角看仿真调度事件的发生
  • #我与Java虚拟机的故事#连载12:一本书带我深入Java领域
  • (C#)if (this == null)?你在逗我,this 怎么可能为 null!用 IL 编译和反编译看穿一切
  • (C++17) std算法之执行策略 execution
  • (回溯) LeetCode 131. 分割回文串
  • (转)C语言家族扩展收藏 (转)C语言家族扩展
  • (转)fock函数详解
  • (转)ORM
  • (转)创业的注意事项
  • ./mysql.server: 没有那个文件或目录_Linux下安装MySQL出现“ls: /var/lib/mysql/*.pid: 没有那个文件或目录”...
  • .axf 转化 .bin文件 的方法
  • .gitignore文件忽略的内容不生效问题解决
  • .Net Attribute详解(上)-Attribute本质以及一个简单示例
  • .Net Framework 4.x 程序到底运行在哪个 CLR 版本之上
  • .NET 将混合了多个不同平台(Windows Mac Linux)的文件 目录的路径格式化成同一个平台下的路径
  • .NET导入Excel数据
  • .one4-V-XXXXXXXX勒索病毒数据怎么处理|数据解密恢复