今天讲一下mysql的数据库引擎中的InnoDb下的行锁、表锁、意向锁等

行锁

mysql的行锁是通过索引加载的,即是行锁是加在索引响应的行上的,要是对应的SQL语句没有走索引,则会全表扫描

行锁类型

  • 共享锁 和 排它锁

共享锁(S锁)

  • 也叫读锁。当一个事务对某几行上读锁时,允许其他事务对这几行进行读操作,但不允许其进行写操作,也不允许其他事务给这几行上排它锁,但允许上读锁。
  • SELECT column FROM table ... LOCK IN SHARE MODE;

排它锁(X锁)

  • 也叫写锁。当一个事务对某几个上写锁时,不允许其他事务写,但允许读。更不允许其他事务给这几行上任何锁。包括写锁。
  • 如果在一条select语句后加上for update,则查询到的数据会被加上一条排它锁,其它事务可以读取,但不能进行更新和插入操作
  • SELECT column FROM table ... FOR UPDATE;

间隙锁

  • 当我们用范围条件而不是相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内并不存在的记录,叫做间隙
  • InnoDB也会对这个"间隙"加锁,这种锁机制就是所谓的间隙锁

表锁

  • 就是没有对没有索引字段上进行事务操作,会导致表锁,其实也可以叫意向锁

意向锁

  • 意向锁产生的主要目的是为了处理行锁和表锁之间的冲突,事务在请求S锁和X锁前,需要先获得对应的IS、IX锁,在为数据行加共享 / 排他锁之前,InooDB 会先获取该数据行所在在数据表的对应意向锁。
  1. 如果没有意向锁的话,则需要遍历所有整个表判断是否有行锁的存在,以免发生冲突
  2. 如果有了意向锁,只需要判断该意向锁与即将添加的表级锁是否兼容即可。因为意向锁的存在代表了,有行级锁的存在或者即将有行级锁的存在。因而无需遍历整个表,即可获取结果
  3. 举例mysql中添加一个排他锁流程是这样的,首先去获取意向排他锁这时会去检测是否有其他已经占用的锁并且是否存在冲突,如果不冲突则获取到意向排他锁,是否存在当前行有排他锁或范围内的间隙锁如果没有则加上排他锁

意向锁类型

  • 意向共享锁 和意向排它锁
  • 意向锁之前是相互兼容的
  • 排他锁持有后其他不管什么锁都是冲突的
  • 下面这个图大家好好好理解下才能懂

mysql ALTER TABLE ADD COLUMN会锁表吗 mysql innodb表锁_表锁