前期数据准备:两张数据表,user 表和 test 表
user表
user表原始数据
test表
test表原始数据
为了演示不同线程对同一个数据库的并发操作,此处开了两个cmd会话窗口(背景颜色作为区分)来模拟不同线程。
一、读锁案例
① 为user表手动添加读锁
② 当前会话可以查询user表记录
(这里记得将 mysql 的返回结果集编码修改为gbk,不然会出现乱码哦)
其他会话也可以查询该表记录
③ 当前会话不能查询和更新其他没有锁定的表(因为当前锁还没释放)
其他会话可以查询和更新其他没有锁定的表
④ 当前会话不能更新(增删改)被锁定的user表(只要是写操作都会被阻塞)
其他会话如果要对锁定的user表更新,则会阻塞,一直等待获得锁。(看到红色箭头指向的那个闪烁的光标了吗!!!我抓了好多次才截到的呜呜呜)
⑤ 当前会话释放锁
其他会话获得锁,完成插入操作
二、写锁案例
① 为user表添加写锁
② 当前会话可以查询别user表记录
③ 当前会话也可以更新user表(可以理解为自己加写锁就是为了自己在修改的时候不让其他人打扰,而前面自己加读锁就只是为了读,所以自己也不能修改)
其他会话对锁定的user表进行查询操作,则会阻塞,一直等待获得锁
既然读操作都给阻塞了,那写操作就更不用说了。
④ 当前会话释放锁
然后其他会话获得锁,完成查询操作
三、总结
- 对 MyISAM 表进行读操作(加读锁),不会阻塞本线程和其他线程对同一表的读请求,但会阻塞本线程和其他线程对同一表的写请求;只有当读锁释放后,才会执行本线程和其他线程的写操作。
- 对 MyISAM 表进行写操作(加写锁),本线程可以对该表进行读和写操作,但会阻塞其他线程对同一表的读和写请求;只有当写锁释放后,才会执行其它线程的读和写操作。
注意:MyISAM 的读写锁调度是写优先,这意味着 MyISAM 不适合做以写为主的表的引擎。因为加了写锁后,其他线程不能做任何操作,大量的更新会使的查询很难得到锁,从而造成永远阻塞。
推荐阅读:MySQL行级锁案例详解