天天看点

如何预防死锁发生

//

如何预防死锁发生

//

在高并发的场景中,我们经常会遇到死锁问题,那么如何预防死锁发生?

结合MySQL官方文档,我们可以整理自己的思路如下。

如何预防死锁:

1、尽量不要主动使用Lock table之类的语句,使用事务去代替此来操作。之前有过开发同学想向DBA申请lock table权限,这个行为本身是不妥当的。

2、如果你的业务对于读没有过高的要求,那么尽量使用RC的隔离级别来代替RR的隔离级别,因为RC隔离级别下写入数据能够避免很多死锁问题的发生,特别是当我们使用显示的锁定读时,例如select for share mode等。

3、开启参数innodb_print_all_deadlocks可以将死锁的信息打印到mysql的error log中,这样有利于我们分析解决问题,但是关于锁的信息可能比较多,当我们解决了问题之后,最好是能把它重新改为关闭。

4、应用程序段在检测到死锁之后,确保有重试机制,并且每一个事务执行的时间应该尽可能小,时间尽可能短,降低死锁发生的概率,

5、在对数据表进行一系列操作之后,如果没问题,应该尽快提交事务,而不要在交互式的命令行中长期持有事务

6、在对表进行多个操作的时候,例如包含delete,insert,update好几种写入操作的时候,尽量包在一个事务里按照固定的顺序执行,不要乱序多并发的执行,否则极易出现死锁。

7、MySQL中的锁是建立在索引的基础上的,因此,不要滥用MySQL的索引,此行为极易引发死锁。

8、如果快照读能够满足性能需求,那么就尽量使用快照读,而不是使用select * from xxx lock in share mode这种锁定读的方法。

9、退而求其次,使用表级锁来代替行级锁,即使存储引擎是Innodb,虽然表级锁锁定了全表的记录,但是至少可以保证不受到死锁的影响。

10、首先,我们可以使用show engine innodb status的方法来分析死锁产生的原因,并设置一个比较短的超时时间,innodb_lock_wait_timeout,这样在发生死锁的时候,可以让锁定的时间变得更短,尽快恢复业务。