概述:

按粒度划分:

表锁

  • lock tables … read/write
  • 加上read,本线程只能读,其他线程只能读
  • 加上whrite,本线程可以写,其他线程不能读也不能写
  • 没有行锁的时候只能直接加表锁来控制并发

    行锁

  • 就是锁住整条记录。

  • InnoDB是通过锁住唯一索引实现的,而且必须是精准匹配的情况,否则会退化为临键锁
  • 保证事物的重要手段

    全局锁

  • 对整个数据库加锁,整个数据库处于只读状态

  • 其他的增删改之类的语句都会被阻塞
  • Flush tables with read lock (FTWRL)
  • 使用场景就是做全库逻辑备份时

    其他锁概念:

    间隙锁

  • 基于非唯一索引,锁定一段范围内的索引记录。

  • 锁住的是左右开区间的范围
  • 例如
    • SELECT * FROM table WHERE id BETWEN 1 AND 10 FOR UPDATE;
    • 锁住的就是(1,10)
  • 间隙锁锁住的是一个区间,而不仅仅是这个区间中的每一条数据。

    临键锁

  • 针对非唯一索引

  • 可以说是一种特殊的间隙锁
  • 锁住的是左开右闭区
  • 一定程度上解决幻读
  • 假设索引记录中age字段有10,20,30三条记录的非唯一索引
    • 执行updatge age=20的记录时,会触发临键锁,锁住(20,30]这个范围,
    • 此时如果插入age=21的记录就会被阻塞

锁详解:

大佬总结的加锁规则

原则 1:

  • 加锁的基本单位是 next-key lock。next-key lock 是前开后闭区间。
  • 查找过程中访问到的对象才会加锁。

    优化 1:

  • 索引上的等值查询,给唯一索引加锁的时候,next-key lock 退化为行锁。

  • 索引上的等值查询,向右遍历时且最后一个值不满足等值条件的时候,next-key lock 退化为间隙锁。

    一个 bug:

  • 唯一索引上的范围查询会访问到不满足条件的第一个值为止。