两者区别

MyISAM 仅仅支持表级锁(table-level locking),一锁就锁整张表,这在并发写的情况下性非常差。InnoDB 不光支持表级锁(table-level locking),还支持行级锁(row-level locking),默认为行级锁。

行级锁的粒度更小,仅对相关的记录上锁即可(对一行或者多行记录加锁),所以对于并发写入操作来说, InnoDB 的性能更高。

表级锁和行级锁对比

<aside> 💡 总结:在 InnoDB 引擎之前,MySQL 只支持表级锁,需要对整张表加锁,这种方式加锁快、不会出现死锁,但是性能较低,而 InnoDB 中新引入了行级锁,它的粒度更小,仅对和当前操作相关的一行或多行记录加锁,能够大大减少数据库操作的冲突,但是加锁的开销大,加锁慢,同时可能出现死锁。

</aside>

<aside> 💡 行级锁产生死锁的举例:

假设有两个事务,分别是事务A和事务B,同时操作同一张表的不同行。

  1. 事务A执行步骤:
  2. 事务B执行步骤:
  3. 事务A执行下一步:
  4. 事务B执行下一步:

现在形成了循环依赖:

由于互相等待对方释放锁,事务A和事务B就陷入了死锁状态,无法继续执行下去。

</aside>

应用场景

<aside> ❓ 哪些操作会加表级锁?哪些操作会加行级锁?

</aside>

表级锁

行级锁

三类表级锁

表锁

  1. 表共享读锁(read lock):只能读不能写,对其他客户端的读操作不影响,但会阻塞其他客户端的写操作

    Untitled

  2. 表独占写锁(write lock):加锁客户端可读可写,其他客户端不能读也不能写

    Untitled

元数据锁(Meta Data Lock)

元数据可以简单地理解为是表结构。

无需显式使用,再访问一张表的时候会自动加上,在表上有活动事务的时候,不可以对元数据进行写入操作。