本文介绍: MySQL中的锁,按照锁的粒度分,分为以下三类全局锁:锁定数据库中的所有表。表级锁:每次操作锁住整张表。行级锁:每次操作锁住对应行数据。

目录

前言

全局锁

表级锁

表锁

元数据锁(MDL)


前言

MySQL中的锁,按照锁的粒度分,分为以下三类

具体语句为

基本语法

  • 自身既可以读也可以写。
  • 其他客户端不能读也不能写,会直接阻塞

查看数据库中元数据锁信息

首先客户端A开启一个事务,在事务中对表中的数据进行增删改查,在执行增删改时,会对表中的这些数据加一个行锁,这时客户端B想在表中加一个表锁,客户端B在添加表锁前,先会去检查当前表中一行数据是否有行锁,如果没有则会去添加表锁。

首先客户端A开启一个事务,在事务中对表的数据进行增删改查,对数据添加行锁的同时,又会给表添加一个意向锁,这时客户端B想要在表中加一个表锁,客户端B就会根据客户端A加的意向锁来判断是否可以成功添加表锁,并且不会再逐行检查数据是否有行锁,效率得到大幅度提升。

行锁(Record Lock):锁定单个行记录的锁,防止其他事务对此行进行updatedelete。在读已提交、可重复隔离级别下都支持

间隙锁(Gap Lock):锁定索引记录间隙(不含该记录),确保索引记录间隙不变,防止其他事务在这个间隙进行insert,产生幻读。在可重复隔离级别下都支持

临键锁(Next-Key Lock):行锁和间隙锁组合,同时锁住数据,并锁住数据前面的间隙Gap。在可重复读隔离级别支持

  • 共享锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排它锁。
  • 排他锁(X):允许获取排他锁的事务更新数据,阻止其他事务获得相同数据集的共享锁和排他锁。

查看行锁情况的SQL语句

现在存在一个主键iduser表,username没有创建索引

一个客户端开启事务,并进行查询。另一个客户端查看行锁数据

此时我们可以看到,MySQL没有对select语句进行加锁。接下来我们手动对select语句加锁

由于行锁中的共享锁是互相兼容的,因此我也可以再另一个客户端进行select语句,此时锁记录表中出现两条锁记录。

当事务提交后,事务涉及到锁也会释放

接下来我们测试update语句

接下来测试对非索引的字段进行条件判断,观察添加的是什么锁

  1. 索引上的等值查询(唯一索引),给不存在的记录加锁时,优化为间隙锁。
  2. 索引上的等值查询(普通索引),向右遍历最后一个值不满足查询需求时,临键锁退化为间隙锁
  3. 索引上的范围查询(唯一索引),会访问到不满足条件的第一个值为止。

展示第一种情况,给不存在的记录加锁。

加下来展示第二种情况,我添加了一个age字段,并创建了普通索引

接下来展示第三种情况,对唯一索引的范围查找

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注