Mysql 事务死锁的模拟以及总结
在navicat 或 cmd 开两个窗口分别模拟事务A和B
注意:我用的是PHPstudy集成环境,MySQL是5.7版本的,这里的MySQL默认设置等待时长和锁定时间都是120秒,所以在下面例子中的步骤要在两分钟内完成,或者修改MySQL的默认设置,把时间调大一点,这样就不用那么赶时间了。
例子一
步骤①
#事务A
begin;
select * from student where id = 2 for update;
步骤②
#事务B
begin;
select * from student where id = 3 for update;
步骤③
#事务A
update student set name=‘xx’ where id = 3; #陷入阻塞,等待中
步骤④
#事务B
update student set name=‘xx’ where id = 2; #Deadlock 死锁产生
例子二
步骤①
#事务A
begin;
update student set name=‘xx’ where id in (3,4,5);
步骤②
#事务B
begin;
update student set name=‘xx’ where id in (6,7,8);
步骤③
#事务A
delete from student where id = 7; #陷入阻塞,等待中
步骤④
#事务B
delete from student where id = 3; #Deadlock 死锁产生
总结:
1.死锁是什么?怎么产生的?
答:死锁是多个事务因为争夺资源而陷入阻塞,相互等待的现象。比如上面的例子中,事务A在等待事务B释放锁,而事务B也在等待事务A释放锁,这种相互等待的现象就会产生死锁。
2.死锁有什么危害或影响?
答:死锁会长期占用数据库的连接资源,影响性能;还可能会造成雪崩效应,拖垮整个应用。
3.当死锁产生时要如何解决?
答:可以先进行手动的kill掉死锁进程,然后分析死锁日志,找到原因在去解决。
4.怎样避免死锁的产生?
答:①获取锁的时候可以按照权重保证顺序获取
②同一个事务可以先锁定所需要的全部资源
③把大事务拆成多个小事务