MySQL中的锁

MySQL中的锁

InnoDB中锁与索引

  • 锁是作用在索引上的.
  • 只有SQL命中索引时,才触发锁.
  • 没有命中索引,则使用表锁.

锁的分类

  1. 粒度锁: 表锁,行锁.
  2. 算法锁: 记录锁,间歇锁,临键锁.
  3. 属性锁: 共享锁,排它锁.
  4. 状态锁: 意向共享锁,意向排它锁.

表锁

  • 上锁时锁住的是整个表.
  • 下一个事务访问该表时,必须等待前一个事务释放锁.
  • 粒度大,加锁简单,容易冲突.

行锁

  • 上锁时锁住的是表的某一行或者多行记录.
  • 其他事务不可以访问同一表中被锁定的行,可以访问其他记录.
  • 粒度小,加锁麻烦,不易冲突,并发高.

记录锁(Record Lock)

  • 锁住的只是表的某一条记录.
  • 出现条件:精准命中,且命中字段为唯一索引.
  • UPDATE user_info SET name = '张三' WHERE id = 1,其中id是唯一索引.
  • 避免重复读和脏读问题.

间歇锁(Gap Lock)

  • 锁住的是某一个区间.
  • 相邻ID间形成空隙时,遵循左开右闭原则.
  • 出现条件:范围查询且未命中索引,只出现在Repeatable read的事务级别.
  • SELECT * FROM user_id WHERE id>1 AND id<4,id为唯一索引.
  • 防止幻读问题.

临键锁(Next-Key Lock)

  • 将查询出来的记录锁住的同时,也把该查询内的所有间隙空间页锁住,再把相邻的下一区间也锁定.
  • SELECT * FROM user_info WHERE id>1 AND id<=13 FOR UPDATE
  • 出现条件:范围查询且命中,查询命中索引.
  • 作用:避免脏读,重复读,幻读问题.

共享锁(Share Lock)/读锁/S锁

  • 对数据加读锁后,其他事务只能对该数据加读锁,不能对数据加写锁.
  • 所有事务释放读锁后,才能加写锁.
  • 支持并发读取,避免重复读.

排他锁(Exclusive Lock)/写锁/X锁

  • 对数据加写锁后,其他请求不能为数据在任何锁,直到写锁释放.
  • 避免脏数据和脏读.

意向锁

当一个事务试图对整个表进行加锁时,需要获得对应类型的意向锁.

意向共享锁

一个事务对整个表进行加共享锁前,首先获得表的意向共享锁.

意向排他锁

一个事务试图对整个表加排他锁前,首先获得表的意向排他锁.

参考:

原文地址:https://www.cnblogs.com/truestoriesavici01/p/13224770.html