一、概念:
多个事务在同一资源上互相占用形成回路。这就是死锁
基本命令:
#查看是否自动提交事务
show variables like '%autocommit%';
#设置事务是否自动提交
set @@autocommit=0;
set @@autocommit=1;
二、例子:
CREATE TABLE `user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`uuid` varchar(255) DEFAULT NULL,
`name` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
INSERT INTO `user` VALUES ('1', '66', '1', '3');
INSERT INTO `user` VALUES ('2', '2', '2', '2');
INSERT INTO `user` VALUES ('3', '3', '3', '3');
事务 A 想修改 id=2 的数据,但是必须要事务 B 释放。事务 B 想要修改 id=1 的数据,同样也在等待事务 A 的结束。
t1 时刻 A 事务执行:START TRANSACTION;select * from user where id=1 for update;
t2 时刻 B 事务执行: START TRANSACTION;select * from user where id=2 for update;
t3 时刻 A 事务执行:update user set id=id where id=2;
t4 时刻 B 事务执行:update user set id=id where id=1;
结束事务命令:commit
三、预防手段:
innodb_lock_wait_timeout InnoDB 的锁超时等待参数
SHOW GLOBAL VARIABLES LIKE 'innodb_lock_wait_timeout';
SET GLOBAL innodb_lock_wait_timeout=100;
合理设计索引
降低隔离级别(看业务是否允许)
大事务拆小,尽量一次性把锁拿全
四、定位死锁:
查看隔离级别 select @@tx_isolation;
查看当前线程 show processlist;
返回结果中包括死锁相关事务的详细信息,如引发死锁的 SQL 语句,事务已经获得的锁,正在等待什么锁,以及被回滚的事务等。据此可以分析死锁产生的原因和改进措施。
show engine innodb status;
重要的三张锁的监控表innodb_trx,innodb_locks,innodb_lock_waits,Tables_in_information_schema数据库下,如果出现死锁这里面会有数据