死锁分析与解决

本文探讨了MySQL中死锁产生的原因、条件以及解决方法,包括互斥、请求与保持、不剥夺和环路等待四个条件。介绍了排他锁(X锁)和共享锁(S锁)的概念,并提供了加锁的SQL语句。防止死锁的策略包括设置锁优先级、固定顺序访问、设置锁超时时间和一次性加锁所有数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

mysql死锁产生与解决
原因:两个两个以上的事务在执行过程中,因争夺锁资源而造成的互相等待的现象
产生条件:

  • 互斥:并大执行的事务为了进行必要的隔离保证执行的正确,在事务结束前,需要对修改的数据库记录持锁,保证多个事务对相同数据库记录串行修改。
  • 请求与保持:已持有一个锁资源,等待另一个锁资源.死锁仅发生在请求两个或两个以上的锁对象
  • 不剥夺:已经获得锁资源的事务,在未执行前,不能被强制剥夺,只能使用完是,由事务自己释放
  • 环路等待:发生死锁时,必然存在一个事务与锁的环形链

在这里插入图片描述
mysql中的锁

  • 排他锁:又称为写锁,简称X锁,顾名思义,排他锁就是不能与其他所并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁,但是获取排他锁的事务是可以对数据就行读取和修改。
  • 共享锁:又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改。

在这里插入图片描述
加锁方式

  • 内部加锁:

    • 共享锁s:select * from table lock in share mode
    • 排他锁x:select * from table for update
  • 外部加锁:为了实现ACID特性,由数据库系统内部自动添加,加锁规则繁琐,与sql执行计划,事务隔离级别,表索引结构有关

避免死锁的方法:
① 设置锁优先级:提前设置优先级,如果运行A和B出现死锁,优先级低的回滚,优先级高的先执行,这样即可解决死锁问题。
② 以固定顺序访问:设定一个顺序,比如先A后B,或者先B后A,保证不管在什么时候都尊重这个顺序(通常是按ID大小的顺序),这样就会减少死锁发生的概率了。
③ 设置锁超时时间set lock_timeout:尝试获取锁的时候加一个锁超时时间,超过这个时间放弃对该锁请求。比如设置A的超时时间为10毫秒,B为100毫秒,A试了10毫秒以后获取不到资源,然后会自动断开,A断开了,这时B就可以获取资源了,避免了死锁。(但是这个方法不太好的地方在于,还需要对A再提交一次,而且timeout时间需要综合很多其他因素去设置)
④ 对所使用的数据全部加锁:每一个事务一次就将所有要使用到的数据全部加锁,否则就不允许执行,比如A在给B转钱的时候,会使用到A账户转账前,A相互转账后,B账户转账前,B账户转账后,所以就算是A给B转账,也要把A.B账户所有信息都一起加锁(这样B想给A转账也不行,因为被锁住了,不过这个还是傻,效率很低,可能又会带来其他死锁问题)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值