1. 锁的分类:

根据加锁范围:

  1. 全局锁
  2. 表级锁
  3. 行锁


2. 全局锁

全局读锁命令

全局锁就是对整个数据库实例加锁,Mysql 提供了一个加全局读锁的命令。可以让整个数据库处于只读状态。

导致数据的增删改、建表修改表语句、事务的提交语句失效。

1
Flush tables with read lock

场景:全库的逻辑备份(**也可以开启可重复读事务级别来进行备份**)

另一种方式是使用 mysqldump 工具使用参数-single-transaction 进行数据库备份。前提:数据库中所有的表支持可重复读。

场景:用户买课和买课后的余额。不加锁导致两个表的数据前后不一致。

3. 表级锁

  1. 两种表锁
  • 表锁
  • 元数据锁
  1. 表锁

作用:锁定表只能进行读或读和写操作。不允许操作其他表。(**处理并发的常用方式**)

1
lock tables t1 read, t2 write;

只能对 t1 表进行读,t2 表进行读和写。直到执行unlock tables之前不允许对其他表进行读写操作。

  1. MDL ( meatadata lock)

作用:保证读写的正确性。防止 DDL(加字段等修改表结构的操作)和 DML 冲突(增删改数据

特点: 自动加上,不需要使用 sql 语句。在对表进行数据的增删改查操作时加读锁。修改表结构时,加写锁。

读读锁共存、读写锁、写写锁互斥。

示例

在多个事务开启且未结束的过程中给某个表添加个字段导致读写锁冲突。

解决方法

在 information_schema 库中 innodb_trx 表中查询出正在执行事务,可以暂停表变更事务、或者是长事务。

4. 小结

  1. 全局锁主要是用来逻辑备份,有两种方式一种是通过命令 flush tables with read lock;。另一种需要支持库中所有的表支持可重复读事务,使用 mysqldump -single-transaction 进行备份。

  2. 表锁通过 sql 语句限制指定表只能进行读、读/写操作,且不允许对其他表操作在解锁前。

  3. MDL 是自动加上的,不需要通过 sql 语句。存在读写锁、写写锁互斥情况。锁在事务提交后释放。作用是为了防止 DDL 和 DML 操作冲突。