ITPub博客

首页 > 数据库 > > SQL Server里解决死锁常用的四种套路

SQL Server里解决死锁常用的四种套路

作者:浪花小雨滴 时间:2020-05-14 16:02:42 0 删除 编辑

常见的四种解决死锁的方法


方法一、调整索引,以调整执行计划,减少锁的申请数目,从而消除死锁

如果死锁的双方不会申请对方要申请的锁,那么死锁也不会发生。如果

数据库设计者能够引导SQL使用seek的执行计划,只读取要返回的数据,

那么申请的锁数量会大大降低,死锁的几率也会减少


(1)死锁双方处理的数据本身没有交叉

如果双方都要修改或返回同样的数据,那么再优化索引,可能也没有用处


(2)DBA要有权力在数据库里调整索引设计



方法二、使用“nolock”参数,让select 语句不要申请S锁,减少锁的申请数目,从而消除死锁

很多死锁发生在S锁上面,我们可以通过在语句里加“nolock”参数的方法,让select语句不要去申请S锁,死锁自然也会消失


这个方法解决死锁可以说是立竿见影,所以很多用户很喜欢使用它

但是缺点很明显,with (nolock)这个参数意味着,select语句将能接收脏读,这是SQLServer支持的最低一级事务隔离级别。用户要能够理解他的副作用,并且能够接受,才能使用

这种方法只能解决S锁参与的死锁问题,如果死锁发生在U锁或X锁上,with (nolock)没有帮助

SELECT * FROM [dbo].[Employee_Demo_Heap] WITH (NOLOCK)




方法三、升级锁粒度,将死锁转化为一个阻塞问题

死锁产生的原因是双方都申请到了一个资源,同时又要申请对方的资源。

如果一方一个资源都没有申请到,那么发生的就是阻塞,而不是死锁

从这个角度讲,如果能想办法让一方被另一方阻塞住,什么资源都申请不到

那死锁就不会发生


从上面的例子里,死锁发生在同一个page上的不同rid上。如果语句直接申请Page

级别的锁,同时就只能有一个人得到锁资源,而另一个人会被阻塞住。因此,

使用pagelock这个参数,也能解决死锁问题。


这种方法虽然不会降低事务隔离级别,但是语句更容易被阻塞住,最终

的并发度难免受到影响。因此实际上也是一种粗鲁的方法。没有第一种

通过加索引的方法那么精细。如果能用第一种方法,还是使用第一种方法

比较负责任

SELECT * FROM [dbo].[Employee_Demo_Heap] WITH (PAGLOCK)




方法四、使用快照隔离级别

由于这个死锁里有S锁参与,这里把事务隔离级别从默认的已提交读

改成快照,对缓解死锁也会有很好帮助。

SET TRANSACTION ISOLATION LEVEL SNAPSHOT

GO


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31537575/viewspace-3154062/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2018-05-16

  • 博文量
    4259
  • 访问量
    39968