InnoDB学习(六)之数据库锁

InnoDB存储引擎的默认隔离级别事可重复读,MVCC多版本并发控制仅仅解决了快照读情况下的数据隔离,而对于当前读,InnoDB通过锁来进行并发控制。

InnoDB锁

本文主要参考了MySQL官方文档,并在上面添加了一些自己的理解,有兴趣看英文的也可以看MySQL官方文档。本文分为以下章节:

  1. 共享锁和独占锁;
  2. 意向锁;
  3. 行锁;
  4. 间隙锁;
  5. Next-Key锁
  6. 插入意向锁;
  7. 自增锁;

共享锁和排他锁

InnoDB锁的最小粒度是行锁,行锁可以分为两大类:共享锁(S)和独占锁(X)。

  • 共享锁:持有某行数据共享锁的事务,可以读取行锁对应行的数据;
  • 独占锁:持有某行数据独占锁的事务,可以修改行锁对应行的数据;

如果事务T1持有行R的共享锁,那么对于事务T2对行R的访问分为两种情况:

  • 如果事务T2请求行R的共享锁,则事务T2可以请求成功,请求完成后事务T1和事务T2同时持有行R的共享锁;
  • 如果事务T2请求行R的排他锁,事务T2会被阻塞,直到事务T1释放锁或者事务超时回滚;

如果事务T1持有行R的共享锁,那么不管事务T2请求R行的共享锁还是排他锁,都会被事务T1阻塞,直到事务T1释放锁或事务T2回滚。

意向锁

InnoDB支持支持多种粒度的锁,比如对于以下两个SQL语句,加锁的对象就完全不同:

  1. SELECT * FROM USER_INFO WHERE ID = 1 FOR UPDATE,其中ID是主键,ID=1的数据行存在,那么这句SQL会获取ID=1的数据行的独占锁;
  2. LOCK TABLES USER_INFO WRITE,其中USER_INFO表存在,那么这句SQL会获取USER_INFO表的独占锁;

表锁和行锁之间也存在互斥的情况,比如表上的独占锁和表中每一行数据的独占锁之间冲突(锁表了当然不允许修改表中的内容),这种互斥要怎么实现呢?InnoDB使用了意向锁实现表锁和行锁之间的互斥,意向锁是表级别的锁,对一行数据添加独占锁或排他锁时,会先向数据行所在的表添加意向锁,意向锁分为两种类型:

  1. 共享意向锁:事务会对表中的某一行数据添加共享锁;
  2. 排他意向锁:事务会对表中的某一行数据添加排他锁;

所以对表添加意向锁的情况也分两种:

  1. 如果事务需要获取某一行数据的共享锁,那么必然会首先获取数据所在表的共享意向锁,如SQL语句SELECT * FROM USER_INFO WHERE ID = 1 LOCK IN SHARE MODE会首先向表USER_INFO添加共享意向锁;
  2. 如果事务需要获取某一行数据的排他锁,那么必然会首先获取数据所在表的排他意向锁,如SQL语句SELECT * FROM USER_INFO WHERE ID = 1 FOR UPDATE
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-御狐神-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值