「MySQL高级篇」MySQL锁机制 && 事务( 二 )

读操作客户端一对book表加了锁,并拿到了book表的锁,在该锁未释放之前,不能去查别的表;而客户端二能查到book和其他表,是因为读锁是共享锁,他并没有真正拿到这把锁,自然可以肆意妄为,不受未释放锁的束缚;

「MySQL高级篇」MySQL锁机制 && 事务

文章插图

「MySQL高级篇」MySQL锁机制 && 事务

文章插图
写操作
  • 客户端①直接报错,因为读锁会排斥写操作
  • 客户端②陷入了阻塞状态,得等待客户端①释放锁

「MySQL高级篇」MySQL锁机制 && 事务

文章插图
  • unlock后,客户端②的写操作就能正常执行了 。

「MySQL高级篇」MySQL锁机制 && 事务

文章插图
总结
  • 读锁对于加锁的客户端:会限制对其他表的查询以及对任何表的写操作
  • 读锁对于其他客户端:不会限制任何查询,但会阻塞对该表的写操作
助记自己拿到了读锁,那自己当然不能再去读其他表,而又因为读锁不会影响到其他客户端读的结果,那其他客户端自然可以任意读 。
而对于写操作:自己还在读,就别想着去做写操作了!而对于其他客户端,如果对该表写操作 。肯定会影响到当前客户端的读取结果,所以其他客户端不能对该表进行写操作
  • 简而言之:自己不能三心二意【操作其他表】,而对他人则考虑自己所做的操作会不会导致两个客户端拿到不一致的数据,会的话就是不允许的 。
写锁案例客户端 一 :
1)获得tb_book 表的写锁
lock table tb_book write ;2)执行查询操作
select * from tb_book ;3)执行更新操作
update tb_book set name = 'java编程思想(第二版)' where id = 1;更新操作执行成功 ;
客户端二 :
4)执行查询操作
select * from tb_book ;
  • 陷入阻塞状态,因为写锁是排他锁,排斥其他客户端的写和读操作 。

「MySQL高级篇」MySQL锁机制 && 事务

文章插图
当在客户端一中释放锁指令 unlock tables 后,客户端二中的 select 语句 就会立即执行
总结
  • 写的优先级很高,对于锁定的表可写可读,但同样不能三心二意!!!而其他客户端对于锁定的表啥也干不了
结论锁模式的相互兼容性如表中所示:
「MySQL高级篇」MySQL锁机制 && 事务

文章插图
由上表可见:
1) 对MyISAM 表的读操作,不会阻塞其他用户对同一表的读请求,但会阻塞其他用户对同一表的写请求;
2) 对MyISAM 表的写操作,则会阻塞其他用户对同一表的读和写操作;
此外,MyISAM 的读写锁调度是写优先,这也是MyISAM不适合做写为主的表的存储引擎的原因 。因为写锁后,其他线程不能做任何操作,大量的更新会使查询很难得到锁,从而造成永远阻塞 。
查看锁的争用情况show open tables;
「MySQL高级篇」MySQL锁机制 && 事务

文章插图
In_user : 表当前被查询使用的次数 。如果该数为零,则表是打开的,但是当前没有被使用 。
Name_locked:表名称是否被锁定 。名称锁定用于取消表或对表进行重命名等操作 。
show status like 'Table_locks%';
「MySQL高级篇」MySQL锁机制 && 事务

文章插图
Table_locks_immediate : 指的是能够立即获得表级锁的次数,每立即获取锁,值加1 。
Table_locks_waited : 指的是不能立即获取表级锁而需要等待的次数,每等待一次,该值加1,此值高说明存在着较为严重的表级锁争用情况 。

经验总结扩展阅读