如何减少SQLServer死锁发生

如何减少SQLServer死锁发生,第1张

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

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

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

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

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( ) spid *** allint bl *** allint)IF @@ERROR<>RETURN

@@ERRORinsert into

#tmp_lock_who(spid bl) select

blockedfrom (select * from sysprocesses where

blocked>)

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

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

blocked>IF

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

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

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

现在没有阻塞和死锁信息

as message 循环开始while @intCounter <= @intCountPropertie *** egin 取第一条记录select

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

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

其执行的SQL语法如下 elseselect

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

进程号SPID + CAST(@bl AS VARCHAR( )) + 阻塞

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

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

return

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

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

按同一顺序访问对象

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

避免事务中的用户交互

避免编写包含用户交互的事务 因为运行没有用户交互的批处理的速度要远远快于用户手动响应查询的速度 例如答复应用程序请求参数的提示 例如 如果事务正在等待用户输入 而用户就去做别的事了 则用户将此事务挂起使之不能完成 这样将降低系统的吞吐量 因为事务持有的任何锁只有在事务提交或回滚时才会释放 即使不出现死锁的情况 访问同一资源的其它事务也会被阻塞 等待该事务完成

保持事务简短并在一个批处理中

在同一数据库中并发执行多个需要长时间运行的事务时通常发生死锁 事务运行时间越长 其持有排它锁或更新锁的时间也就越长 从而堵塞了其它活动并可能导致死锁 保持事务在一个批处理中 可以最小化事务的网络通信往返量 减少完成事务可能的延迟并释放锁

使用低隔离级别

确定事务是否能在更低的隔离级别上运行 执行提交读允许事务读取另一个事务已读取(未修改)的数据 而不必等待第一个事务完成 使用较低的隔离级别(例如提交读)而不使用较高的隔离级别(例如可串行读)可以缩短持有共享锁的时间 从而降低了锁定争夺

使用绑定连接

使用绑定连接使同一应用程序所打开的两个或多个连接可以相互合作 次级连接所获得的任何锁可以象由主连接获得的锁那样持有 反之亦然 因此不会相互阻塞

下面有一些对死锁发生的一些建议

)对于频繁使用的表使用集簇化的索引

)设法避免一次性影响大量记录的T SQL语句 特别是INSERT和UPDATE语句

)设法让UPDATE和DELETE语句使用索引

)使用嵌套事务时 避免提交和回退冲突

lishixinzhi/Article/program/SQLServer/201311/22240

帮你找到了,虽然我也不懂这方面的知识

但是相信你看完以后就会明白了

http://203.208.35.101/search?q=cache:Rp7MAD6Sfr8J:www.dc9.cn/post/IISAspDeadLock.html+%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%AD%BB%E9%94%81%E7%9A%84%E5%8E%9F%E5%9B%A0%E6%98%AF&hl=zh-CN&ct=clnk&cd=9&gl=cn&client=aff-os-maxthon&st_usg=ALhdy29xlQJbG7rDS0ezUrWsw0janJEHBA

第一,内存泄漏

C/C++程序还可能产生另一个指针问题:丢失对已分配内存的引用。当内存是在子程序中被分 配时,通常会出现这种问题,其结果是程序从子程序中返回时不会释放内存。如此一来,对已分配的内存的引用就会丢失,只要操作系统还在运行中,则进程就会一 直使用该内存。这样的结果是,曾占用更多的内存的程序会降低系统性能,直到机器完全停止工作,才会完全清空内存。

第二,C指针错误

用C或C++编写的程序,如Web服务器API模块,有可能导致系统的崩溃,因为只要间接引 用指针(即,访问指向的内存)中出现一个错误,就会导致操作系统终止所有程序。另外,使用了糟糕的C指针的Java模拟量(analog)将访问一个空的 对象引用。Java中的空引用通常不会导致立刻退出JVM,但是前提是程序员能够使用异常处理方法恰当地处理错误。在这方面,Java无需过多的关注,但 使用Java对可靠性进行额外的度量则会对性能产生一些负面影响。

第三,数据库中的临时表不够用

许多数据库的临时表(cursor)数目都是固定的,临时表即保留查询结果的内存区域。在临时表中的数据都被读取后,临时表便会被释放,但大量同时进行的查询可能耗尽数目固定的所有临时表。这时,其他的查询就需要列队等候,直到有临时表被释放时才能再继续运行。

第四,线程死锁

由多线程带来的性能改善是以可靠性为代价的,主要是因为这样有可能产生线程死锁。线程死锁 时,第一个线程等待第二个线程释放资源,而同时第二个线程又在等待第一个线程释放资源。我们来想像这样一种情形:在人行道上两个人迎面相遇,为了给对方让 道,两人同时向一侧迈出一步,双方无法通过,又同时向另一侧迈出一步,这样还是无法通过。双方都以同样的迈步方式堵住了对方的去路。假设这种情况一直持续 下去,这样就不难理解为何会发生死锁现象了。

第五,磁盘已满

导致系统无法正常运行的最可能的原因是磁盘已满。一个好的网络管理员会密切关注磁盘的使用情况,隔一定的时间,就需要将磁盘上的一些负载转存到备份存储介质中(例如磁带)。

日志文件会很快用光所有的磁盘空间。Web服务器的日志文件、SQL*Net的日志文件、 JDBC日志文件,以及应用程序服务器日志文件均与内存泄漏有同等的危害。可以采取措施将日志文件保存在与操作系统不同的文件系统中。日志文件系统空间已 满时Web服务器也会被挂起,但机器自身被挂起的几率已大大减低。

第六,服务器超载

Netscape Web服务器的每个连接都使用一个线程。Netscape Enterprise Web服务器会在线程用完后挂起,而不为已存在的连接提供任何服务。如果有一种负载分布机制可以检测到服务器没有响应,则该服务器上的负载就可以分布到其 它的Web服务器上,这可能会致使这些服务器一个接一个地用光所有的线程。这样一来,整个服务器组都会被挂起。操作系统级别可能还在不断地接收新的连接, 而应用程序(Web服务器)却无法为这些连接提供服务。用户可以在浏览器状态行上看到connected(已连接)的提示消息,但这以后什么也不会发生。

总之,还有许多因素也极有可能导致Web香港服务器租用或香港服务器托管站点无法工作。有许多种原因可能导致Web站点无法正常工作,这使得系统地检查所有问题变得很困难。


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/616700.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-07-14
下一篇2023-07-14

发表评论

登录后才能评论

评论列表(0条)

    保存