在mysql数据库中,锁是基于存储引擎的,不同的存储引擎,采用的锁机制是不一样的。
常用存储引擎:MyISAM,MEMORY,InnoDB。
锁的类型:行级锁,页面锁,表级锁
具体对应关系:
存储引擎 | 支持锁的类型 |
---|---|
MYISAM | 表级锁 |
MEMORY | 页面锁 |
INNODB | 行级锁 |
三种锁类型的特性:
表级锁:
开销小,加锁快,不会出现死锁;
锁定粒度大,发生锁冲突的概率最高,并发度低;
行级锁:
开销大,加锁慢,会出现死锁;
锁定粒度小,发生锁冲突的概率最低,并发度最高;
页面锁:
开销,加锁速度位于表级锁和行级锁之间,会出现死锁;
锁定粒度,发生锁冲突的概率位于表级锁和行级锁之间,并发度一般;
-
MyISAM类型的存储引擎只支持表级别的锁,表级锁的工作机制如下:
对MYISAM表的读操作,不会阻塞其它用户对同一张表的读请求,但会阻塞对同一张表的写请求;
对MYISAM表的写操作,则会阻塞其它用户对同一表的读和写操作;MYISAM表的读操作与写操作之间,以及写操作与写操作之间是串行的;当一个线程获得对一个表的写操作后,只有持有锁的线程可以对表进行更新操作,其它线程的读写操作都会等待,直到锁被释放为止。
实例演示:
搭建环境:
- 创建MYISAM类型的表:
2.插入一条数据:
对MyISAM表的读操作演练:
a.获得test1表的read锁
b.打开第二个客户端窗口,读操作正常
c.对第二个客户端进行写操作(焦点一直闪烁,因为表已经被A客户端锁定了,写操作需要等待A释放锁)
d.客户端A进行锁释放,客户端B成功获取锁并且执行插入操作成功
对MyISAM表的写操作锁:
a.给A客户端加上写锁
b.对客户端B进行读写操作
总结:根据上面结果,当只是一个客户端获取了read锁的时候,其它客户端可以进行正常读取操作,但是会阻塞写操作;当一个客户端获取了write锁的时候,其它客户端读写操作都会被阻塞,直至释放锁才可以继续执行。
(注意:MYISAM的表在执行查询语句前,会自动给涉及的所有表加读锁,在执行更新,插入,删除前,会自动给涉及的表加写锁,这里显示加锁,只是为了方便测试)