MySQL的锁分类

1.存储引擎使用的锁

  • MyISAM和MEMORY存储引擎采用的表级锁
  • InnoDB存储引擎既支持行级锁,也支持表级锁,默认情况下采用行级锁
  • BDB采用的是页面锁,也支持表级锁

2.锁分类

  • 数据操作的类型分

    • 读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会互相影响
    • 写锁(排他锁):当前写操作没有完成前,它会阻断其他写锁和读锁
  • 按照数据操作的粒度分

    • 表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低
    • 行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高
    • 页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般
  • 按照操作性能可分

    • 乐观锁:一般的实现方式是对记录数据版本进行比对,在数据更新提交的时候才会进行冲突检测, 如果发现冲突了,则提示错误信息
    • 悲观锁:在对一条数据修改的时候,为了避免同时被其他人修改,在修改数据之前先锁定,再修改 的控制方式。共享锁和排他锁是悲观锁的不同实现,但都属于悲观锁范畴
  • 锁兼容

    • 共享锁只能兼容共享锁, 不兼容排它锁
    • 排它锁互斥共享锁和其它排它锁

加锁语法

1.表级锁(偏读)

  • 查看是否加锁
  1. -- 0表示没有加锁,当前的所有数据库表都没有加锁
  2. SHOW OPEN TABLES;
  3. -- 查询加锁的表,条件In_use 大于0
  4. SHOW OPEN TABLES WHERE In_use > 0;
  • 加锁格式
  1. -- 语法格式: LOCK TABLE 表名 READ(WRITE), 表名2 READ(WRITE), 其他;
  2. -- mylock01加读锁(共享锁) , mylock02加写锁(排他锁)
  3. lock table mylock01 read;
  4. lock table mylock02 write;
  • 解锁方式
  1. -- 方式1
  2. UNLOCK TABLES;
  3. -- 方式2 找到锁进程,得到id
  4. SHOW PROCESSLIST;
  5. kill id;

2.行级锁(偏写)

  • 使用MySQL行级锁的两个前提

    • 使用 innoDB 引擎
    • 开启事务 (隔离级别为Repeatable Read)
  • 加共享锁(S):select * from table_name where ... lock in share mode;

  • 加排他锁(x):select * from table_name where ... for update;

行级锁都是基于索引的,如果一条SQL语句用不到索引是不会使用行级锁的,而会使用表级锁把 整张表锁住

更新时间:{docsify-updated}