在讨论锁之前,可能会引入事务的隔离级别。尴尬的说,有点忘记了。
数据库死锁相对还比较常见,突然也让我想到了goroutine
的deadlock
。说下我的理解:死锁,其实是一种无尽的相互等待。
尝试通俗地描述一下死锁的过程:
- 路人甲和路人乙合租,两人公用一个卫生间
- 早上,路人甲醒的早,直接去了卫生间,但没有带手纸。想等路人乙醒了之后给他送手纸
- 路人乙起床后,拿上了手纸,想等路人甲赶紧从卫生间出来
昨晚,线上环境又deadlock
报警。遗憾的是,虽然我知道发生死锁的原因,但不知道原因的原因。最后还是根据DBA
同事提供的日志得出了判断。
在分析之前,先通过如下表格,了解一下数据库常见的锁:
X | IX | S | IS | |
---|---|---|---|---|
X | Conflict | Conflict | Conflict | Conflict |
IX | Conflict | Compatible | Conflict | Compatible |
S | Conflict | Conflict | Compatible | Compatible |
IS | Conflict | Compatible | Compatible | Compatible |
简化描述一下,昨晚线上死锁的情况。下面对语句做了简化:
事务一
update friends set name = "道道法" where id = 1
事务二
update friends set name = "道道法" where id = 1
事务三
update friends set name = "道道法" where id = 1
事务一抢先获取了行X
锁。而此时,事务二、事务三会请求去获取行的IX
锁。当事务一释放的X
锁之后,事务二和事务三必然就发生了DeadLock
。
来源:oschina
链接:https://my.oschina.net/u/3017278/blog/3195508