如何减少SQL Server死锁发生

  次阅读 来源:互联网(转载协议) 2016-03-01 10:19 我要评论(0)

死锁是指在某组资源中,两个或两个以上的线程在执行过程中,在争夺某一资源时而造成互相等待的现象,若无外力的作用下,它们都将无法推进下去,死时就可能会产生死锁,这些永远在互相等待的进程称为死锁线程。简单的说,进程A等待进程B释放他的资源,B又等待A释放他的资源,这样互相等待就形成死锁。

如在数据库中,如果需要对一条数据进行修改,首先数据库管理系统会在上面加锁,以保证在同一时间只有一个事务能进行修改操作。如事务1的线程 T1具有表A上的排它锁,事务2的线程T2 具有表B上的排它锁,并且之后需要表A上的锁。事务2无法获得这一锁,因为事务1已拥有它。事务2被阻塞,等待事务1。然后,事务1需要表B的锁,但无法获得锁,因为事务2将它锁定了。事务在提交或回滚之前不能释放持有的锁。因为事务需要对方控制的锁才能继续操作,所以它们不能提交或回滚,这样数据库就会发生死锁了。

如在编写存储过程的时候,由于有些存储过程事务性的操作比较频繁,如果先锁住表A,再锁住表B,那么在所有的存储过程中都要按照这个顺序来锁定它们。如果无意中某个存储过程中先锁定表B,再锁定表A,这可能就会导致一个死锁。而且死锁一般是不太容易被发现的。

如果服务器上经常出现这种死锁情况,就会降低服务器的性能,所以应用程序在使用的时候,我们就需要对其进行跟踪,使用sp_who和sp_who2来确定可能是哪些用户阻塞了其他用户,我们还可以用下面的存储过程来跟踪具体的死锁执行的影响:

create procedure sp_who_lock

as

begin

declare @spid int,@bl int,@intTransactionCountOnEntry

int,@intRowcount

int,@intCountProperties

int,@intCounter

int create table

#tmp_lock_who

(id int identity(1,1),spid smallint,bl smallint)IF @@ERROR<>0 RETURN

@@ERRORinsert into

#tmp_lock_who(spid,bl) select

0 ,blockedfrom (select * from sysprocesses where

blocked>0 )

a where not exists(select * from (select * from sysprocesses where blocked>0 )

b where a.blocked=spid)union select spid,blocked from sysprocesses where

blocked>0IF

@@ERROR<>0 RETURN @@ERROR -- 找到临时表的记录数select

@intCountProperties = Count(*),@intCounter = 1from #tmp_lock_whoIF

@@ERROR<>0 RETURN @@ERROR if @intCountProperties=0select

'现在没有阻塞和死锁信息'

as message-- 循环开始while @intCounter <= @intCountPropertiesbegin-- 取第一条记录select

@spid = spid,@bl = blfrom #tmp_lock_who where id = @intCounter beginif @spid =0 select

'引起数据库死锁的是: '+ CAST(@bl AS VARCHAR(10)) + '进程号,

其执行的SQL语法如下'elseselect

'进程号SPID:'+ CAST(@spid AS VARCHAR(10))+ '被' +

'进程号SPID:'+ CAST(@bl AS VARCHAR(10)) +'阻塞,

当前进程执行的SQL语法如下'DBCC INPUTBUFFER (@bl )end --

循环指针下移set @intCounter = @intCounter + 1enddrop table #tmp_lock_who

return 0

我们只需要通过在查询分析器里面执行sp_who_lock,就可以具体捕捉到执行的堵塞进程,这时我们就可以对对应的SQL语句或者存储过程进行性能上面的改进及设计。

所以我们在数据库设计的时候,虽然不能完全避免死锁,但可以使死锁的数量尽量减少。增加事务的吞吐量并减少系统开销,因为只有很少的事务,所以就得遵循下面的原则:

按同一顺序访问对象

如果所有并发事务按同一顺序访问对象,则发生死锁的可能性会降低。在写SQL语句或存储过程的时候,就需要按照顺序在两个并发事务中先获得表A上的锁,然后获得表B上的锁,当第一个事务完成之前,另一个事务被阻塞在表A上。第一个事务提交或回滚后,第二个事务继续进行,而不能在语句里面写先获得表B上的锁,然后再获得表A的锁。

本站部分文章来源于网络以及网友投稿,本站只负责对文章进行整理、排版、编辑,是出于传递更多信息之目的,并不意味着赞同其观点或证实其内容的真实性。如果您有什么意见或建议,请联系QQ28-1688-302!

人工智能实验室
相关文章相关文章
  • 让AI触手可及  Qualcomm携手创通联达推出全新终端侧AI开发套件

    让AI触手可及 Qualcomm携手创通联达推出全新终端侧AI开发套件

  • 品友互动为Digital Travel APAC2018 唯一受邀中国AI企业

    品友互动为Digital Travel APAC2018 唯一受邀中国AI企业

  • 长虹新款智能语音空调,告诉你空调也能玩Siri

    长虹新款智能语音空调,告诉你空调也能玩Siri

  • 第一批国家重点研发计划公布,旷视科技开启“五年行动”

    第一批国家重点研发计划公布,旷视科技开启“五年行动”

网友点评网友点评
阅读推荐阅读推荐

据外媒报道,STEER打造了首款完全自动驾驶停车技术,旨在使常规车辆转变为无人驾驶车辆。STEER的首款技术应用是4级自动驾驶及网络安全停车...

近日,美国软性机器抓手制造商 Soft Robotics 宣布,获得 2000 万美元的融资,本轮投资者包括 Scale Venture Partners,Calibrate Ventures...

据外媒报道,加州车管局发布了《2017自动驾驶脱离报告(California Autonomous Vehicle Disengagement Reports)》,其中谈及了脱离的具体...

用人机语音交互,来解决智能家居适老的问题;通过家庭门禁与安防套件、空气净化套件、可燃气体与有害气体监控套件等相互联动,在不同生活情...