mysql产生死锁_MySQL会发生死锁吗?

MySQL的InnoDB引擎事务有4种隔离级别,主要是为了保证数据的一致性。

InnoDB引擎提供了行级锁,表锁。MyISAM提供了表锁,如题,MySQL会发生死锁吗?

会,在InnoDB引擎下,RR(REPEATABLE-READ)级别,如果多个事务争抢同一个资源,会发生死锁。在RR级别下,MySQL提供了next-key lock。假如一个索引的行有10,11,13,20

那么可能的next-key lock的包括:

(无穷小, 10]

(10,11]

(11,13]

(13,20]

(20, 无穷大)

即:当你查询12时,如果数据未查到,那么将对(12,13]范围内的数据进行锁定。next-key lock的定义可以到官方具体查看,这里做个演示。

CREATE TABLE `user` (

`id` int(11) unsigned NOT NULL AUTO_INCREMENT,

`name` varchar(200) DEFAULT NULL,

`age` int(11) DEFAULT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=1111 DEFAULT CHARSET=utf8;

format,png

image-20190304142624761

//查看隔离级别,

show variables like '%tx_isolation%';

// 设置隔离界别

SET [SESSION | GLOBAL] TRANSACTION ISOLATION LEVEL {READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE}

// 不设置自动提交

SET autocommit = 0;

死锁演示

首先将隔离级别都设置为RR级别的,并且不让事务自动提交

根据上面的数据,在事务1中查询

// 得到空结果集,此时锁定的范围是(33,100]

select * FROM user where id=33 for update;

在事务2中也进行查询

// 查询到空的结果,在事务2中锁定的范围是(34,100]

select * FROM user where id=34 for update

在事务1中插入数据

// 虽然事务1锁定了范围,事务2也锁定了范围

insert into user values(35,'ac',10);

format,png

image-20190304143355381

在事务2中也插入数据

insert into user values(34,'ac',10)

format,png

image-20190304143707234

可以发现已经发生了死锁

解决办法

设置死锁的超时时长

innodb_lock_wait_timeout=500

查询到当前正在锁定的事务线程,将其杀死

// 可以看到正在运行的事务线程,还有运行状态

SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;

//trx_mysql_thread_id为上一条命令获取的结果,将具体的数字替换一下即可。

kill trx_mysql_thread_id

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值