Mysql内部通过锁机制实现对资源的并发访问控制,保证数据的一致性,锁机制的类型和引擎的种类有关,MyISAM中默认支持的表级锁有两种:共享读锁和独占写锁。表级锁在MyISAM和InnoDB的存储引擎中都支持,但是InnoDB默认支持的是行锁。

MyISAM锁机制

Mysql中可以通过以下sql来显示的在事务中显式的进行加锁和解锁操作:

1
2
3
4
5
6
// 显式的添加表级读锁
LOCK TABLE 表名 READ
// 显示的添加表级写锁
LOCK TABLE 表名 WRITE
// 显式的解锁(当一个事务commit的时候也会自动解锁)
unlock tables;

(1)MyISAM表级写锁:当一个线程获取到表级写锁后,只能由该线程对表进行读写操作,别的线程必须等待该线程释放锁以后才能操作。

(2)MyISAM表级共享读锁:当一个线程获取到表级读锁后,该线程只能读取数据不能修改数据,其它线程也只能加读锁,不能加写锁。

InnoDB锁机制

InnoDB和MyISAM不同的是,InnoDB支持行锁和事务,InnoDB中除了有表锁和行级锁的概念,还有Gap Lock(间隙锁)、Next-key Lock锁,间隙锁主要用于范围查询的时候,锁住查询的范围,并且间隙锁也是解决幻读的方案。

InnoDB中的行级锁是对索引加的锁,在不通过索引查询数据的时候,InnoDB就会使用表锁。

但是通过索引查询的时候是否使用索引,还要看Mysql的执行计划,Mysql的优化器会判断是一条sql执行的最佳策略。

若是Mysql觉得执行索引查询还不如全表扫描速度快,那么Mysql就会使用全表扫描来查询,这是即使sql语句中使用了索引,最后还是执行为全表扫描,加的是表锁。