前言:
之前分析了间隙锁以及行锁导致死锁的案例,后来我在学习插入意向锁的过程中,了解到单纯地插入操作也可能会导致死锁,所以也模拟下这种场景,以后遇到类似问题也不至于慌乱.
同一条插入sql引发的死锁
环境准备
1.创建表:
CREATE TABLE `test_user` (
`user_id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` char(10) DEFAULT NULL,
`status` int(10) DEFAULT NULL,
`unqiue_id` bigint(20) NOT NULL,
PRIMARY KEY (`user_id`),
UNIQUE KEY `index_unique` (`unqiue_id`) USING BTREE,
KEY `index_user` (`name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
2.插入数据:
INSERT INTO `test_user` VALUES ('1', 'a', '1', '1');
INSERT INTO `test_user` VALUES ('3', 'c', '2', '2');
INSERT INTO `test_user` VALUES ('5', 'e', '3', '3');
模拟死锁
1.启动事务A.
mysql> start transaction;
Query OK, 0 rows affected (0.01 sec)
mysql> insert into test_insert_deadlock(id,name,age) values(1,'大兄弟',25);
Query OK, 1 row affected (0.00 sec)
2.启动事务B(插入阻塞).
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test_insert_deadlock(id,name,age) values(1,'大兄弟',25);
3.启动事务C(插入阻塞).
mysql> start transaction;
Query OK, 0 rows affected (0.01 sec)
mysql> insert into test_insert_deadlock(id,name,age) values(1,'大兄弟',25);
4.回滚事务A.
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
结果
事务A正常回滚,事务B正常执行插入sql,事务C发生死锁
分析:
1.在模拟死锁步骤3时 查看innodb状态信息:show engin innodb status\G;
事务B在执行插入操作
---TRANSACTION 118519640, ACTIVE 3 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(