Mysql锁的种类以及加锁情况

  • 锁的种类
  • 按照锁粒度
  • 按照是否可写
  • 另外两个表级锁
  • 加锁的情况
  • 怎么上读锁或者写锁
  • 关于是表锁还是行锁?
  • for update锁的情况


锁的种类

按照锁粒度

表锁:
Mysql中锁定 粒度最大 的一种锁,对当前操作的整张表加锁,实现简单 ,资源消耗也比较少,加锁快,不会出现死锁 。

行锁:
行级锁能大大减少数据库操作的冲突。其加锁粒度最小,并发度高,但加锁的开销也最大,加锁慢,会出现死锁。 InnoDB支持的行级锁,包括如下几种。

  • Record Lock: 对索引项加锁,锁定符合条件的行。其他事务不能修改和删除加锁项;【该锁是对索引记录进行加锁!锁是在加索引上而不是行上的】
  • Gap Lock: 对索引项之间的“间隙”加锁,其他事务不能在锁范围内插入数据,这样就防止了别的事务新增幻影行
  • Next-key Lock: 锁定索引项本身和索引范围。即Record Lock和Gap Lock的结合。可解决幻读问题。

按照是否可写

共享锁(s): 假设事务T1对数据A加上共享锁,那么事务T2可以读数据A,不能修改数据A。其它事务还是可以对A加共享锁的

排他锁(X): 假设事务T1对数据A加上排他锁,那么事务T2不能读数据A,不能修改数据A。其他事务不能再加任何锁

insert,delete,update在事务中都会自动默认加上排它锁【行级】,只有LOCK TABLE … READLOCK TABLE … WRITE才能申请表级别的锁。

另外两个表级锁

另外两个表级锁:

  • 意向共享锁(IS): 表示事务准备给数据行记入共享锁,事务在一个数据行加共享锁前必须先取得该表的IS锁。
  • 意向排他锁(IX): 表示事务准备给数据行加入排他锁,事务在一个数据行加排他锁前必须先取得该表的IX锁。
  • 这里的意向锁是表级锁,表示的是一种意向,仅仅表示事务正在读或写某一行记录,在真正加行锁时才会判断是否冲突。意向锁是InnoDB自动加的,不需要用户干预。
  • IX,IS是表级锁,不会和行级的X,S锁发生冲突,只会和表级的X,S发生冲突
  • 意向锁之间互不排斥,但除了 意向共享锁 与 共享锁兼容外,意向锁会与 共享锁 / 排他锁 互斥【此处的锁指的都是表级锁】

意向锁存在的目的?

假设事务T1,用排他锁来锁住了表上的几条记录,那么此时表上存在意向排它锁。那么此时事务T2要进行LOCK TABLE … WRITE的表级别锁的请求,可以直接根据意向锁是否存在而判断是否有锁冲突。

加锁的情况

首先我们要知道

  1. 只有在可重复读和串行化的隔离级别下才有gapLock。
  2. 串行化,该级别下读写串行化,且所有的select语句后都自动加上lock in share mode,即使用了共享锁。因此在该隔离级别下,使用的是当前读,而不是快照读

怎么上读锁或者写锁

上共享锁(读锁)的写法:lock in share mode

上排它锁(写锁)的写法:for update

关于是表锁还是行锁?

并不是用表锁来实现锁表的操作,而是利用了Next-Key Locks,也可以理解为是用了行锁+间隙锁来实现锁表的操作!

mysql的各种锁 mysql中的锁种类_mysql


如果隔离级别为读未提交和读已提交,无论条件列上是否有索引,都不会锁表,只锁行!,因为没有gaplock

for update锁的情况

行锁情况:查询条件中为主键、索引字段,且索引不为null并且生效的情况下是行锁,索引字段检索多条时,也是行级锁,组合索引,也是行级锁

表锁:查询条件非主键、非索引字段,或者说索引未生效的情况下是表锁

无锁:查询无符合条件记录时,无锁