数据库锁---MyISAM的表锁

2022-03-23 20:05:27 浏览数 (1)

锁的分类:

对数据库操作的粒度分:行锁,表锁

对数据操作的类型分:读锁,写锁

读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会互相影响;

写锁(排它锁):当前写操作没有完成前,它会阻断其他写锁和读锁;

三种锁:

表锁(偏读):

偏向MyISAM引擎,开销小,加锁快;无死锁;锁定力度大,发生锁冲突的概率最高,并发度最低

我们测试一下MyISAM引擎的锁

建立一张表 指定使用myisam引擎

代码语言:javascript复制
create table mylock (
id int not null primary key auto_increment,
name varchar(20) default ''
) engine myisam;

insert into mylock(name) values('a');
insert into mylock(name) values('b');
insert into mylock(name) values('c');
insert into mylock(name) values('d');
insert into mylock(name) values('e');

测试锁 我们需要打开两个连接测试 我们命名为session1 session2

测试上锁:

查看表上的锁

代码语言:javascript复制
show  open tables;

现在还没有锁

给mylock表上读锁 book上写锁

代码语言:javascript复制
lock table mylock read,book write;

我们在查看表上的锁

代码语言:javascript复制
show open tables;

这两个表有了锁

解锁操作

代码语言:javascript复制
unlock tables;
show open tables;

上锁操作测试完了 我们来测试一下读锁会有哪些锁定限制

加上读锁

代码语言:javascript复制
lock table mylock read;

两个连接进行查询 都可以查询的到

这时我们使用session1(也就是对表加读锁的那个连接)进行数据修改

可以看到报错了

代码语言:javascript复制
 Table 'mylock' was locked with a READ lock and can't be updated */

表已经被锁定无法更新

那这个是后这时候我们这个session1连接能访问其他的表么

我们用锁定表的session1连接测试读取其他表

代码语言:javascript复制
select *  from book;

结论是不能

我们再用session2连接 测试读取其他表

我们可以看到是可以的

那seession2连接可以修改当前表么

我们可以看到 会一直阻塞 知道session把表的锁释放才执行

代码语言:javascript复制
结论:被读锁锁定期间  锁定表的线程可以读取锁定的表   修改锁定的表不可以   读取别的表也不可以
其他线程:可以读取锁定的表,可以读取其他线程  ,修改锁定的表会一直阻塞到session1表的读锁释放才执行

读锁测试完了 我们在测试一下写锁

把当前所有的锁释放

代码语言:javascript复制
unlock tables;

mylock表加上写锁

代码语言:javascript复制
lock tables mylock write;

session1连接测试修改自己

代码语言:javascript复制
update mylock set name='a1' where id=1;

修改成功

session2测试修改

代码语言:javascript复制
update  mylock set name='a11' where id=1;

又阻塞了

这时我们session1释放写锁

session2写成功

我们session1再加锁进行测试

代码语言:javascript复制
lock tables mylock write;

session1读取其他表 还是无法读取 锁没有释放

session2读取其他表

代码语言:javascript复制
select * from  book;

成功

session2查询mylock表

会一直阻塞到session1释放锁

代码语言:javascript复制
结论:session1可以对锁定的表进行增删改查  session2对当前的表进行操作会一直阻塞到锁释放 

MyISAM在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行增删改操作前,会自动给涉及的所有表加写锁 总结: 1.对MyISAM表的读操作,不会阻塞其它进程对同一表的读请求,但会阻塞对同一表的锁请求,只有当锁释放了后才会执行其他线程的写操作。 2.对MyISAM表的写操作,会阻塞其它进程对同一张表的读和写操作,只有当锁释放了之后,才会执行其他进程的读写操作。

0 人点赞