MYSQL-死锁大集合

为什么会死锁

数据准备

建个表

CREATE TABLE `t_order` (
  `id` int NOT NULL AUTO_INCREMENT,
  `order_no` int DEFAULT NULL,
  `create_date` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `index_order` (`order_no`) USING BTREE
) ENGINE=InnoDB ;

存个数据

MYSQL-死锁大集合_第1张图片

 然后我们分别创建两个事务 

事务A:插入订单 1007 

事务B:插入订单 1008

由于插入之前要检测(for update)是否已经存在该条记录 所以执行流程是这样的

MYSQL-死锁大集合_第2张图片

我们要知道 锁只是针对其他事务的 且锁只在本事务结束后才能释放

首先事务Aselect: 会锁住(1006,正无穷)

事务B select:会锁住(1006,正无穷)

(间隙锁可以共存 但是Next-key锁因为包含记录锁所以不能共存)

事务A insert 1007的下一条记录 找到了表示最大的虚拟记录 在间隙上放插入意向锁 然后发现这个间隙上面有事务B的间隙锁 阻塞(插入意向锁等待状态)

事务B insert 1008的下一条记录 找到了表示最大的虚拟记录 找到了表示最大的虚拟记录 在间隙上放插入意向锁 然后发现上面有事务B的间隙锁 阻塞

然后A和B因为insert操作阻塞 所以事务一直存在 所以锁一直存在 所以死锁

死锁的四个条件

互斥、占有且等待、不可强占用、循环等待

如何排查死锁

提示出现死锁:ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

我们就知道死锁发生了

通过SHOW ENGINE INNODB STATUS;来查看死锁日志:

根据死锁日志分析循环等待的场景,然后根据当前各个事务执行的SQL分析出加锁类型以及顺序,逆向推断出如何形成循环等待,这样就能找到死锁产生的原因了。

你可能感兴趣的:(mysql,数据库)