MySQL学习——InnoDB 的锁类型

InnoDB 的锁类型

读锁(共享锁)、写锁(排他锁)、意向锁和MDL锁。

  1. 读锁
    读锁简称 S 锁,一个事务获取了一个事务行的读锁,其他事务也能够获取到该行对应的读锁,但不能获得写锁,即一个事务在读取数据时,其他事务也可以读,但不能对该数据进行增删改的操作。
    读锁有两种select 方式。第一种是自动提交模式下的 select 查询语句,不需要加任何锁,直接返回查询结果,这就是一致性非锁定读。第二种是通过 select … lock in share mode 在被读取的行记录或者行记录的范围上加一个读锁,让其他事务可以读,但是要想申请加锁就会被阻塞。
  2. 写锁
    写锁简称 X 锁,一个事务获取了一个数据行的写锁,其他事务就不能获取该行的其他锁,写锁的优先级最高。一些 DML 语句的操作都会对行记录加写锁。select for update 也会对读取的行记录加上一个写锁,其他事务不能再对被锁定的行进行加任何锁,否则会发生堵塞。
  3. MDL 锁(meta data lock)
    MDL锁是 MySQL5.5之后才引入的,目的是为了保证表中的元数据的信息。在会话 A 中开启了查询事务后,会自动获得一个 DML 锁,会话 B 不可用执行任何 DDL 语句操作。

只开启事务,不查询时的运行结果
在这里插入图片描述

  1. 意向锁
    在 MySQL 存储引擎 InnoDB 中,意向锁是表级锁。意向锁有两种类型:意向共享锁、意向排他锁。
    意向共享锁(IS)是指在一个数据行加共享锁前必须取得该表的 IS 锁。
    意向排他锁(IX)是指在一个数据行加排他锁前必须取得该表的 IX 锁。
    意向锁和MDL 的作用类似,都是防止在事务进行的过程中,执行 DDL 语句的操作而导致数据的不一致。

InnoDB 行锁种类

InnoDB 在默认的事务隔离级别为 RR ,并且参数 innodb_locks_unsafe_for_binlog = 0 的模式下,行锁的种类有三种。

  1. 单个行记录锁(record lock)
    在InnoDB中,当查询条件字段上存在索引时,多个会话更新同一行记录事务时会出现锁等待的现象,更新不同的行记录不会出现锁等待。

    当查询条件字段上不存在索引或者包含不存在索引的字段时,多个会话更新同一行记录事务时会出现锁等待的现象,更新同一表中不同的行记录也会出现锁等待。即对表中某一行数据进行操作时,对表中所有的行记录加了锁。

    InnoDB 的锁是加在索引项上面的。

查询条件不添加索引的执行效果:
在这里插入图片描述

  1. 间隙锁
    在RR 这个隔离级别,为了避免幻读现象,引入了 Gap lock。但它只锁定行记录数据的范围,不包含记录本身,即不允许在此范围内插入任何数据。

开启一个会话A,在事务中查询 ttt表中 score > 124的记录,在上面加一个共享锁;
开启一个会话B,往表中插入一个 score 大于124的记录以及一个 score 小于 124的记录,大于score 大于124的记录插入一直处于等待状态,score 小于124 的记录很快就能插入成功。
在这里插入图片描述
在这里插入图片描述

间隙锁只是针对 RR 隔离级别才管用,它是用来避免幻读现象发生的。

  1. Next-key Locks (记录锁和间隙锁的组合)
    Next-key Locks 是记录锁和间隙锁的组合,当 InnoDB 扫描索引记录时,会先对选中的索引记录加上记录锁 , 再对索引记录的两边的间隙加上间隙锁(Gap Lock)。
    例如:
    在查询 ttt 表score >128 的语句上加上一个写锁,即
 select * fromttt where score > 128 for update;

在另一个事务中,往表中插入 score=128 的记录,无法成功插入,出现锁超时。Next-key Locks 锁不光锁住了 score >128 这个范围,还锁住了128 这个值的本身。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值