
1.是否支持行级锁
MyISAM 只有表级锁,而InnoDB 支持行级锁和表级锁,默认为行级锁。
(1)MySQL大致可以归纳为以下3种锁:
- 表级锁:开销小,加锁快;不会出现死锁;锁的粒度大,发生锁冲突的概率最高,并发度最低。
- 行级锁:开销大,加锁慢;会出现死锁;锁的粒度小,发生锁冲突的概率最低,并发度最高。
- 页面锁:开销 和加锁时间界于表锁和行锁之间;会出现死锁,锁定的粒度界于表锁和行锁之间,并发一般。
(2)表锁
MyISAM会在执行select语句前,会自动给涉及的表加读锁,在执行增删改操作前会自动给涉及的表加写锁。
- MySQL的表锁有两种模式: 
  - 表共享读锁
- 表独占写锁
 
- 读锁会阻塞写,写锁会阻塞读和写。 
  - 对MyISAM表的读操作,不会阻塞其它进程对同一表的读请求,但会阻塞对同一表的写请求。只有当读锁释放后,才会执行其它线程的写操作。
- 对MyISAM表的写操作,会阻塞其它进程对同一表的读和写操作,只有当写锁释放后,才会执行其它进程的读写操作。
 
读锁的演示

窗口1执行

窗口2的语句被阻塞

关闭窗口1,窗口2才执行成功

执行unlock tables释放锁

释放后才成功

create table dept(
    deptno int not null auto_increment,
    dname varchar(20),
    loc varchar(20),
    primary key(deptno)
)ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
# 打开两个会话窗口
# 窗口1执行以下语句
lock table dept read;
select * from dept;
# 窗口2执行执行以下语句
select * from dept;
insert into dept values(null,'财务部','北京');
# 此时,窗口2的请求被阻塞,必须等待会话1释放锁后才能执行;
# 释放会话1的锁,并观察会话2的执行结果。
unlock tables;
写锁的演示
会话1加写锁,会话2读操作,会被阻塞

会话1 释放锁

# 会话1加写锁
lock table dept write;
delete from dept where deptno = 1;
# 会话2读操作,会被阻塞
select * from dept;
# 会话1 释放锁
unlock tables;
# 观察会话2 查询结果
注意:如果持有表锁的session异常终止的话(比如说执行了“ctrl+z”),那么该session是不会主动释放锁的,这时候我们可以重启mysql服务器,不推荐。可以通过show processlist 命令来查看线程ID,通过kill 【线程ID】

总结:MyISAM不适合写表的引擎,写锁后,其它线程不能做任何操作。













![[算法训练营] 回溯算法专题(一)](https://img-blog.csdnimg.cn/b3efdab8a5ab408d877492e912cf2aab.png)





