跳至主要內容

MySQL意向共享锁、意向排他锁

张威大约 4 分钟mysqlmysql锁机制

MySQL 意向共享锁、意向排他锁

![image-20240420193947369](MySQL 意向共享锁、意向排他锁.assets/image-20240420193947369.png)

一、InnoDB表级锁

我们知道,InnoDB是支持行锁,但不是每次都获取行锁,如果不使用索引的,那还是获取的表锁。而且有的时候,我们希望直接去使用表锁

适合使用表索的情况

在绝大部分情况下都应该使用行锁,因为事务的并发效率比表锁更高,但个别情况下也使用表级锁:

  • 事务需要更新大部分或全部数据,表又比较大,如果使用默认的行锁,给大部分行都加锁(此时不如直接加表锁),不仅这个事务执行效率低,而且可能造成其他事务长时间等待和锁冲突

  • 事务涉及多个表,比较复杂,如果都用行锁,很可能引起死锁,造成大量事务回滚

表索的相关命令

当我们希望获取表锁时,可以使用以下命令:

LOCK TABLE user READ  -- 获取这张表的读锁
LOCK TABLE user WRITE -- 获取这张表的写锁

事务执行...

COMMIT/ROLLBACK;      -- 事务提交或者回滚
UNLOCK TABLES;        -- 本身自带提交事务,释放线程占用的所有表锁

在使用表锁的时候,涉及到效率的问题

如果我们

假如这张表有1000万个数据,那我怎么知道这1000万行哪些有行锁哪些没有行锁呢?

除了挨个检查,没有更好的办法,这就导致效率低下的问题

我们这里学习的意向共享锁和意向排他锁就是用来解决,由于需要加表锁而去挨个遍历数据,确定是否有某些数据被加了行锁,而导致的效率低下问题。作用就是快速判断表里是否有记录被加锁

二、意向共享锁和意向排他锁(表锁而非行锁)

意向锁的作用:为了可以更快速的

意向共享锁(IS锁):事务在给一行记录加共享锁前,必须先取得该表的IS锁 意向排他锁(IX锁):事务在给一行记录加排他锁前,必须先取得该表的IX锁

![](MySQL 意向共享锁、意向排他锁.assets/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAQnVnTWFrZXItc2hlbg==,size_20,color_FFFFFF,t_70,g_se,x_16.png)

(上面表格所有的锁都是针对整表

  1. 之前,由InnoDB存储引擎自动加上表的IS或IX锁,我们无法手动获取IS或IX锁
  2. 意向锁之间都兼容,不会产生冲突
  3. 意向锁存在的意义是为了更高效的获取表锁(表格中的X、S、IX、IS指的是表锁,不是行锁)
  4. 意向锁是表级锁,协调表锁和行锁的共存关系,主要目的是显示事务正在锁定某行或者试图锁定某行。

分析事务1获取行X锁和事务2获取表S锁:

首先事务1需要给表的第10行数据加X锁,于是InnoDB存储引擎自动给整张表加上了IX锁。当事务2再想获取整张表的S锁时,看到这张表已经有别的事务获取了IX锁了,就说明这张表肯定有某些数据被加上了X锁,这就导致事务2不能给整张表加S锁了。此时事务2只能等待,无法成功获取表S锁

当某个事务要获取表的X锁时,不需要再检查哪些行被加上了X或S锁,只需要检查整表是否被加上IX或IS锁即可