暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

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

SQLServer走起 2021-02-10
3767

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

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

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

数据库设计者能够引导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

文章转载自:

https://www.cnblogs.com/lyhabc/articles/3222228.html

文章经作者授权转载,版权归原文作者所有

图片来源于网络,侵权必删!

文章转载自SQLServer走起,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论