11.MySql的死锁

By youfang

Mysql

行锁和表锁

在mysql 的 InnoDB引擎支持行锁,与Oracle不同,mysql的行锁是通过索引加载的,即是行锁是加在索引响应的行上的,要是对应的SQL语句没有走索引,则会全表扫描,

行锁则无法实现,取而代之的是表锁。

表锁:不会出现死锁,发生锁冲突几率高,并发低。

行锁:会出现死锁,发生锁冲突几率低,并发高。

锁冲突:例如说事务A将某几行上锁后,事务B又对其上锁,锁不能共存否则会出现锁冲突。(但是共享锁可以共存,共享锁和排它锁不能共存,排它锁和排他锁也不可以)

死锁:例如说两个事务,事务A锁住了15行,同时事务B锁住了610行,此时事务A请求锁住610行,就会阻塞直到事务B施放610行的锁,而随后事务B又请求锁住15行,事务B也阻塞直到事务A释放15行的锁。死锁发生时,会产生Deadlock错误。

原理

1
2
3
4
5
6
7
8
9
10
-- 测试1
BEGIN;
SELECT * FROM student ;
update student set name = 1 where name = '马腾';
ROLLBACK;

-- 测试1
set autocommit = 0;--Spring中的开启事务方式
UPDATE student SET name = 1181 WHERE age = 38;
rollback;

解决方案

1
2
3
4
5
6
7
8
9
10
11
#### Mysql死锁(方案一)
查看事务加锁情况:show engine innodb status;
show variables like 'innodb_status_output_locks';
set GLOBAL innodb_status_output_locks=ON;

#### Mysql死锁(方案二)
-- 查询InnoDB引擎事务情况
SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
-- 查询trx_mysql_thread_id,使用命令kill
-- kill trx_mysql_thread_id;
kill 790;