死锁
死锁的介绍
- 多个并发事务(2个或者以上);
- 每个事务都持有锁(或者是已经在等待锁);
- 每个事务都需要再继续持有锁;
- 事务之间产生加锁的循环等待,形成死锁。
演示案例
-- 事务A执行
BEGIN;
UPDATE users SET lastUpdate = NOW() WHERE id =1;
UPDATE t2 SET `name`='test' WHERE id =1;
ROLLBACK;
-- 事务B执行
BEGIN;
UPDATE t2 SET `name`='test' WHERE id =1;
UPDATE users SET lastUpdate = NOW() WHERE id =1;
ROLLBACK;
事务A和事务B按照上面的执行步骤,最后因为存在相互等待的情况,所以 MySQL 判断出现死锁了。
死锁的避免
- 类似的业务逻辑以固定的顺序访问表和行。
- 大事务拆小。大事务更倾向于死锁,如果业务允许,将大事务拆小。
- 在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁概率。
- 降低隔离级别,如果业务允许,将隔离级别调低也是较好的选择
- 为表添加合理的索引。可以看到如果不走索引将会为表的每一行记录添加上锁(或者说是表锁)
作者:殷建卫 链接:https://www.yuque.com/yinjianwei/vyrvkf/dluggd 来源:殷建卫 - 架构笔记 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。