-- Mysql锁的分类,死锁的原因和排查解决办法
【官网】:https://dev.mysql.com/doc/refman/8.0/en/sql-transactional-statements.html
在存在并发执行的数据库事务中,死锁是常见的.当两个事务需要一组有冲突的锁,而不能将事务继续下去的话,就会出现死锁,严重影响应用的正常执行
mysql
我们需要搞清楚锁的分类和原理才能避免事务并发执行过程产生的死锁问题,最大长度降低避性能,issue等的产生.在存在并发执行的数据库事务中,死锁是常见的.当两个事务需要一组有冲突的锁,而不能将事务继续下去的话,就会出现死锁,严重影响应用的正常执行。
无
在数据库并发执行事务的上下文中,死锁是指两个或多个事务因为相互依赖进而无法执行完成的情况--因为每个事务都在等待另外一个事务释放资源。相互之间形成一个循环依赖,循环等待。 每个事务都在等待链中的对面那个事务释放资源,其关系如图所示:
select @@tx_isolation;
select * from information_schema.innodb_locks
show engine innodb status
[注]开启数据库记录所有死锁日志(在.mysql.ini种)
log_warnings=1 (开启MySQL的警告日志) innodb_print_all_deadlocks=1 (开启死锁日志)
检测sql:
select * from tb_UserBalance where id=150221 for update;
死锁时报错:
SQL错误[12131[400011: Deadlock found when trying to get lock; try restarting transaction
[注1] 上述sql要获取lock时遇到死锁,获取lock失败,建议重启事务。
[注2] mysql默认事务50秒超时 。
c1)终止并回滚事务
通常是通过中止其中一个事务并回滚其更改.
c2)强制释放某些事务资源.
(d1). 尽量减少事务持有锁的时间
当事务持有锁的时间越长,死锁的可能性就越大。
(d2).统一加锁顺序
当多个事务需要访问同一组资源时,应该按照统一的加锁顺序进行操作,避免不同的事务加锁顺序不一致而导致死锁。
(d3).尽量减小事务的范围
在进行数据库操作时,应该尽量减小事务的范围,避免在一个事务中同时操作多个表,从而减少死锁的可能性。
(d4).合理设置事务隔离级别
不同的事务隔离级别会对死锁的产生和解决产生不同的影响。因此,应该根据具体的业务需求和系统负载情况,合理设置事务隔离级别,以尽可能地避免死锁的发生。
例如在执行长时间查询时,可以使用事务的 READ UNCOMMITTED 隔离级别来避免持有锁。
(d5)尽量使用索引
使用索引可以提高数据库的查询性能,并且减少锁的竞争。因此,在进行数据库设计和优化时,应该尽可能地使用索引,减少数据库的锁竞争。