mysql 第8.17章 事务-死锁 mysql 第8.17章 事务-死锁

27分钟前

一、问题

数据库的死锁是怎么产生的?两个事务抢锁,谁也不让谁就产生死锁了。

出现死锁了怎么排查和解决?

二、死锁的原理

死锁的原理特别好理解,比如:你和朋友去吃饭,你拿了筷子,他拿了,你要等他的碗才能吃饭,他要等你筷子才能吃饭,你们两个谁也不松手,然后就僵在这里了,这个就是死锁。

对应到数据库里面,必须同时满足 4 个条件才会出现死锁:

  1. 互斥条件:一个锁同一时间只能被一个事务持有,就像筷子同一时间只能由一个人去用

  2. 持有并等待:我已经拿了一个锁,还要等着拿另一个锁,手里的锁呢我还不松手

  3. 不可剥夺:别人拿的锁我不能硬抢,只能等别人自己释放

  4. 循环等待:a 等 b 的锁,b 等 a 的锁,形成了一个死循环

这 4 个条件同时满足就形成了死锁。

三、死锁的解决

3.1、SQL

show engine innodb status

这个语句会清楚的告诉你哪两个事务产生了死锁,这个两个事务分别执行了什么 SQL,抢的是什么类型的锁,最后数据库自动回滚了哪一个事务

3.2、业务代码找问题

拿着死锁的日志里面的两个 SQL 语句,去找对应的业务代码。

90% 的情况都是事务执行顺序反了:比如说事务 1 先改订单表,再改用户表;事务 2 先改用户表,再改订单表;刚好形成一个循环等待

3.3、检查不必要锁

看是不是锁的粒度太大了:比如明明应该加行锁的,结果因为字段没有加索引,导致了锁所有的行。

普通查询加了一些没必要的悲观锁:比说 for update 导致锁的范围变大了,更容易产生冲突




阅读 2

mysql文章
带到手机上看