在上一篇章咱们讲了行级锁的原理,你们看到这里的话应该也了解得差很少了,咱们这里再来说讲经过对行级锁的认识学习以后,应该注意和避免的点。php
在咱们使用锁的时候,有一个问题是须要注意和避免的,咱们知道,排它锁有互斥的特性。一个事务或者说一个线程持有锁的时候,会阻止其余的线程获取锁,这个时候会形成阻塞等待,若是循环等待,会有可能形成死锁。mysql
这个问题咱们须要从几个方面来分析,一个是锁为何不释放,第二个是被阻塞了怎么办,第三个死锁是怎么发生的,怎么避免。咱们且看正文部分。程序员
老规矩,先上飞机票:面试
前面提到的脑图以下,想要完整高清图片能够到微信个人公众号下【6曦轩】下回复 MySQL 脑图获取: 算法
回顾:锁何时释放?sql
事务结束(commit,rollback);客户端链接断开。数据库
若是一个事务一直未释放锁,其余事务会被阻塞多久?会不会永远等待下去?若是是,在并发访问比较高的状况下,若是大量事务因没法当即得到所需的锁而挂起,会占用大量计算机资源,形成严重性能问题,甚至拖跨数据库。性能优化
[Err] 1205 - Lock wait timeout exceeded; try restarting transaction MySQL 有一个参数来控制获取锁的等待时间,默认是 50 秒。bash
show VARIABLES like 'innodb_lock_wait_timeout';
复制代码
对于死锁,是不管等多久都不能获取到锁的,这种状况,也须要等待 50 秒钟吗?那微信
不是白白浪费了 50 秒钟的时间吗?
咱们先来看一下何时会发生死锁。
死锁演示:
Session 1 | Session 2 |
---|---|
begin; select * from t2 where id =1 for update; |
|
- | begin; delete from t2 where id =4 ; |
update t2 set name= '4d' where id =4 ; | |
- | delete from t2 where id =1 ; |
在第一个事务中,检测到了死锁,立刻退出了,第二个事务得到了锁,不须要等待 50 秒:
[Err] 1213 - Deadlock found when trying to get lock; try restarting transaction
为何能够直接检测到呢?是由于死锁的发生须要知足必定的条件,因此在发生死锁时,InnoDB 通常都能经过算法(wait-for graph)自动检测到。
那么死锁须要知足什么条件?死锁的产生条件:
由于锁自己是互斥的 (1)同一时刻只能有一个事务持有这把锁; (2)其余的事务须要在这个事务释放锁以后才能获取锁,而不能够强行剥夺; (3)当多个事务造成等待环路的时候,即发生死锁。
举例:
理发店有两个总监。一个负责剪头的 Tony 总监,一个负责洗头的 Kelvin 总监。
Tony 不能同时给两我的剪头,这个就叫互斥。
Tony 在给别人在剪头的时候,你不能让他停下来帮你剪头,这个叫不能强行剥夺。若是 Tony 的客户对 Kelvin 总监说:你不帮我洗头我怎么剪头?Kelvin 的客户对 Tony 总监说:你不帮我剪头我怎么洗头?这个就叫造成等待环路。
若是锁一直没有释放,就有可能形成大量阻塞或者发生死锁,形成系统吞吐量降低,这时候就要查看是哪些事务持有了锁。
SHOW STATUS 命令中,包括了一些行锁的信息:
show status like 'innodb_row_lock_%';
复制代码
SHOW 命令是一个概要信息。InnoDB 还提供了三张表来分析事务与锁的状况:
select * from information_schema.INNODB_TRX; -- 当前运行的全部事务 ,还有具体的语句
复制代码
select * from information_schema.INNODB_LOCKS; -- 当前出现的锁
复制代码
select * from information_schema.INNODB_LOCK_WAITS; -- 锁等待的对应关系
复制代码
找出持有锁的事务以后呢?
若是一个事务长时间持有锁不释放,能够 kill 事务对应的线程 ID ,也就是 INNODB_TRX 表中的 trx_mysql_thread_id,例如执行 kill 4,kill 7,kill 8。
固然,死锁的问题不能每次都靠 kill 线程来解决,这是治标不治本的行为。咱们应该尽可能在应用端,也就是在编码的过程当中避免。
有哪些能够避免死锁的方法呢?
有问题?能够给我留言或私聊 有收获?那就顺手点个赞呗~
固然,也能够到个人公众号下「6曦轩」,
回复“学习”,便可领取一份 【Java工程师进阶架构师的视频教程】~
回复“面试”,能够得到: 【本人呕心沥血整理的 Java 面试题】
回复“MySQL脑图”,能够得到 【MySQL 知识点梳理高清脑图】
因为我咧,科班出身的程序员,php,Android以及硬件方面都作过,不过最后仍是选择专一于作 Java,因此有啥问题能够到公众号提问讨论(技术情感倾诉均可以哈哈哈),看到的话会尽快回复,但愿能够跟你们共同窗习进步,关于服务端架构,Java 核心知识解析,职业生涯,面试总结等文章会不按期坚持推送输出,欢迎你们关注~~~