SQL Server2000中死锁经验总结

摘要:
将死锁减至最少虽然不能完全避免死锁,但可以使死锁的数量减至最少。使用低隔离级别。这样将降低系统的吞吐量,因为事务持有的任何锁只有在事务提交或回滚时才会释放。这时我们可以使用以下存储过程来检测,就可以查出引起死锁的进程和SQL语句。SQLServer自带的系统存储过程sp_who和sp_lock也可以用来查找阻塞和死锁,但没有这里介绍的方法好用。
死锁减至最少
虽然不能完全避免死锁,但可以使死锁的数量减至最少。将死锁减至最少可以增加事务的吞吐量并减少系统开销,因为只有很少的事务:
  • 回滚,而回滚会取消事务执行的所有工作。
  • 由于死锁时回滚而由应用程序重新提交。
下列方法有助于最大限度地降低死锁
  • 按同一顺序访问对象。
  • 避免事务中的用户交互。
  • 保持事务简短并在一个批处理中。
  • 使用低隔离级别。
  • 使用绑定连接。
按同一顺序访问对象
如果所有并发事务按同一顺序访问对象,则发生死锁的可能性会降低。例如,如果两个并发事务获得 Supplier 表上的锁,然后获得 Part 表上的锁,则在其中一个事务完成之前,另一个事务被阻塞在 Supplier 表上。第一个事务提交或回滚后,第二个事务继续进行。不发生死锁。将存储过程用于所有的数据修改可以标准化访问对象的顺序。
SQL Server2000中死锁经验总结第1张
避免事务中的用户交互
避免编写包含用户交互的事务,因为运行没有用户交互的批处理的速度要远远快于用户手动响应查询的速度,例如答复应用程序请求参数的提示。例如,如果事务正在等待用户输入,而用户去吃午餐了或者甚至回家过周末了,则用户将此事务挂起使之不能完成。这样将降低系统的吞吐量,因为事务持有的任何锁只有在事务提交或回滚时才会释放。即使不出现死锁的情况,访问同一资源的其它事务也会被阻塞,等待该事务完成。
保持事务简短并在一个批处理中
在同一数据库中并发执行多个需要长时间运行的事务时通常发生死锁。事务运行时间越长,其持有排它锁或更新锁的时间也就越长,从而堵塞了其它活动并可能导致死锁
保持事务在一个批处理中,可以最小化事务的网络通信往返量,减少完成事务可能的延迟并释放锁。
使用低隔离级别
确定事务是否能在更低的隔离级别上运行。执行提交读允许事务读取另一个事务已读取(未修改)的数据,而不必等待第一个事务完成。使用较低的隔离级别(例如提交读)而不使用较高的隔离级别(例如可串行读)可以缩短持有共享锁的时间,从而降低了锁定争夺。
使用绑定连接
使用绑定连接使同一应用程序所打开的两个或多个连接可以相互合作。次级连接所获得的任何锁可以象由主连接获得的锁那样持有,反之亦然,因此不会相互阻塞
检测死锁
如果发生死锁了,我们怎么去检测具体发生死锁的是哪条SQL语句或存储过程?
这时我们可以使用以下存储过程来检测,就可以查出引起死锁进程SQL语句。SQL Server自带的系统存储过程sp_who和sp_lock也可以用来查找阻塞和死锁, 但没有这里介绍的方法好用。
SQL Server2000中死锁经验总结第2张usemaster
SQL Server2000中死锁经验总结第2张
go
SQL Server2000中死锁经验总结第2张
createproceduresp_who_lock
SQL Server2000中死锁经验总结第2张
as
SQL Server2000中死锁经验总结第2张
begin
SQL Server2000中死锁经验总结第2张
declare@spidint,@blint,
SQL Server2000中死锁经验总结第2张
@intTransactionCountOnEntryint,
SQL Server2000中死锁经验总结第2张
@intRowcountint,
SQL Server2000中死锁经验总结第2张
@intCountPropertiesint,
SQL Server2000中死锁经验总结第2张
@intCounterint
SQL Server2000中死锁经验总结第2张
SQL Server2000中死锁经验总结第2张
createtable#tmp_lock_who(
SQL Server2000中死锁经验总结第2张id
intidentity(1,1),
SQL Server2000中死锁经验总结第2张spid
smallint,
SQL Server2000中死锁经验总结第2张bl
smallint)
SQL Server2000中死锁经验总结第2张
SQL Server2000中死锁经验总结第2张
IF@@ERROR<>0RETURN@@ERROR
SQL Server2000中死锁经验总结第2张
SQL Server2000中死锁经验总结第2张
insertinto#tmp_lock_who(spid,bl)select0,blocked
SQL Server2000中死锁经验总结第2张
from(select*fromsysprocesseswhereblocked>0)a
SQL Server2000中死锁经验总结第2张
wherenotexists(select*from(select*fromsysprocesseswhereblocked>0)b
SQL Server2000中死锁经验总结第2张
wherea.blocked=spid)
SQL Server2000中死锁经验总结第2张
unionselectspid,blockedfromsysprocesseswhereblocked>0
SQL Server2000中死锁经验总结第2张
SQL Server2000中死锁经验总结第2张
IF@@ERROR<>0RETURN@@ERROR
SQL Server2000中死锁经验总结第2张
SQL Server2000中死锁经验总结第2张
--找到临时表的记录数
SQL Server2000中死锁经验总结第2张
select@intCountProperties=Count(*),@intCounter=1
SQL Server2000中死锁经验总结第2张
from#tmp_lock_who
SQL Server2000中死锁经验总结第2张
SQL Server2000中死锁经验总结第2张
IF@@ERROR<>0RETURN@@ERROR
SQL Server2000中死锁经验总结第2张
SQL Server2000中死锁经验总结第2张
if@intCountProperties=0
SQL Server2000中死锁经验总结第2张
select'现在没有阻塞和死锁信息'asmessage
SQL Server2000中死锁经验总结第2张
SQL Server2000中死锁经验总结第2张
--循环开始
SQL Server2000中死锁经验总结第2张
while@intCounter<=@intCountProperties
SQL Server2000中死锁经验总结第2张
begin
SQL Server2000中死锁经验总结第2张
--取第一条记录
SQL Server2000中死锁经验总结第2张
select@spid=spid,@bl=bl
SQL Server2000中死锁经验总结第2张
from#tmp_lock_whowhereId=@intCounter
SQL Server2000中死锁经验总结第2张
begin
SQL Server2000中死锁经验总结第2张
if@spid=0
SQL Server2000中死锁经验总结第2张
select'引起数据库死锁的是:'+CAST(@blASVARCHAR(10))+'进程号,其执行的SQL语法如下'
SQL Server2000中死锁经验总结第2张
else
SQL Server2000中死锁经验总结第2张
select'进程号SPID:'+CAST(@spidASVARCHAR(10))+''+'进程号SPID:'+CAST(@blASVARCHAR(10))+'阻塞,其当前进程执行的SQL语法如下'
SQL Server2000中死锁经验总结第2张
DBCCINPUTBUFFER(@bl)
SQL Server2000中死锁经验总结第2张
end
SQL Server2000中死锁经验总结第2张
SQL Server2000中死锁经验总结第2张
--循环指针下移
SQL Server2000中死锁经验总结第2张
set@intCounter=@intCounter+1
SQL Server2000中死锁经验总结第2张
end
SQL Server2000中死锁经验总结第2张
SQL Server2000中死锁经验总结第2张
droptable#tmp_lock_who
SQL Server2000中死锁经验总结第2张
SQL Server2000中死锁经验总结第2张
return0
SQL Server2000中死锁经验总结第2张
end
SQL Server2000中死锁经验总结第2张
死锁进程
如何去手动的杀死进程和锁?最简单的办法,重新启动服务。但是这里要介绍一个存储过程,通过显式的调用,可以杀死进程和锁。
SQL Server2000中死锁经验总结第2张usemaster
SQL Server2000中死锁经验总结第2张
go
SQL Server2000中死锁经验总结第2张
SQL Server2000中死锁经验总结第2张
ifexists(select*fromdbo.sysobjectswhereid=object_id(N'[dbo].[p_killspid]')andOBJECTPROPERTY(id,N'IsProcedure')=1)
SQL Server2000中死锁经验总结第2张
dropprocedure[dbo].[p_killspid]
SQL Server2000中死锁经验总结第2张
GO
SQL Server2000中死锁经验总结第2张
SQL Server2000中死锁经验总结第2张
createprocp_killspid
SQL Server2000中死锁经验总结第2张
@dbnamevarchar(200)--要关闭进程的数据库名
SQL Server2000中死锁经验总结第2张
as
SQL Server2000中死锁经验总结第2张
declare@sqlnvarchar(500)
SQL Server2000中死锁经验总结第2张
declare@spidnvarchar(20)
SQL Server2000中死锁经验总结第2张
SQL Server2000中死锁经验总结第2张
declare#tbcursorfor
SQL Server2000中死锁经验总结第2张
selectspid=cast(spidasvarchar(20))frommaster..sysprocesseswheredbid=db_id(@dbname)
SQL Server2000中死锁经验总结第2张
open#tb
SQL Server2000中死锁经验总结第2张
fetchnextfrom#tbinto@spid
SQL Server2000中死锁经验总结第2张
while@@fetch_status=0
SQL Server2000中死锁经验总结第2张
begin
SQL Server2000中死锁经验总结第2张
exec('kill'+@spid)
SQL Server2000中死锁经验总结第2张
fetchnextfrom#tbinto@spid
SQL Server2000中死锁经验总结第2张
end
SQL Server2000中死锁经验总结第2张
close#tb
SQL Server2000中死锁经验总结第2张
deallocate#tb
SQL Server2000中死锁经验总结第2张
go
SQL Server2000中死锁经验总结第2张
SQL Server2000中死锁经验总结第2张
--用法
SQL Server2000中死锁经验总结第2张
execp_killspid'newdbpy'
SQL Server2000中死锁经验总结第2张
查看锁信息
如何查看系统中所有锁的详细信息?在企业管理管理器中,我们可以看到一些进程和锁的信息,这里介绍另外一种方法。
SQL Server2000中死锁经验总结第2张--查看锁信息
SQL Server2000中死锁经验总结第2张
createtable#t(req_spidint,obj_namesysname)
SQL Server2000中死锁经验总结第2张
SQL Server2000中死锁经验总结第2张
declare@snvarchar(4000)
SQL Server2000中死锁经验总结第2张,
@ridint,@dbnamesysname,@idint,@objnamesysname
SQL Server2000中死锁经验总结第2张
SQL Server2000中死锁经验总结第2张
declaretbcursorfor
SQL Server2000中死锁经验总结第2张
selectdistinctreq_spid,dbname=db_name(rsc_dbid),rsc_objid
SQL Server2000中死锁经验总结第2张
frommaster..syslockinfowherersc_typein(4,5)
SQL Server2000中死锁经验总结第2张
opentb
SQL Server2000中死锁经验总结第2张
fetchnextfromtbinto@rid,@dbname,@id
SQL Server2000中死锁经验总结第2张
while@@fetch_status=0
SQL Server2000中死锁经验总结第2张
begin
SQL Server2000中死锁经验总结第2张
set@s='select@objname=namefrom['+@dbname+']..sysobjectswhereid=@id'
SQL Server2000中死锁经验总结第2张
execsp_executesql@s,N'@objnamesysnameout,@idint',@objnameout,@id
SQL Server2000中死锁经验总结第2张
insertinto#tvalues(@rid,@objname)
SQL Server2000中死锁经验总结第2张
fetchnextfromtbinto@rid,@dbname,@id
SQL Server2000中死锁经验总结第2张
end
SQL Server2000中死锁经验总结第2张
closetb
SQL Server2000中死锁经验总结第2张
deallocatetb
SQL Server2000中死锁经验总结第2张
SQL Server2000中死锁经验总结第2张
select进程id=a.req_spid
SQL Server2000中死锁经验总结第2张,数据库
=db_name(rsc_dbid)
SQL Server2000中死锁经验总结第2张,类型
=casersc_typewhen1then'NULL资源(未使用)'
SQL Server2000中死锁经验总结第2张
when2then'数据库'
SQL Server2000中死锁经验总结第2张
when3then'文件'
SQL Server2000中死锁经验总结第2张
when4then'索引'
SQL Server2000中死锁经验总结第2张
when5then''
SQL Server2000中死锁经验总结第2张
when6then''
SQL Server2000中死锁经验总结第2张
when7then''
SQL Server2000中死锁经验总结第2张
when8then'扩展盘区'
SQL Server2000中死锁经验总结第2张
when9then'RID(行ID)'
SQL Server2000中死锁经验总结第2张
when10then'应用程序'
SQL Server2000中死锁经验总结第2张
end
SQL Server2000中死锁经验总结第2张,对象id
=rsc_objid
SQL Server2000中死锁经验总结第2张,对象名
=b.obj_name
SQL Server2000中死锁经验总结第2张,rsc_indid
SQL Server2000中死锁经验总结第2张
frommaster..syslockinfoaleftjoin#tbona.req_spid=b.req_spid
SQL Server2000中死锁经验总结第2张
SQL Server2000中死锁经验总结第2张
go
SQL Server2000中死锁经验总结第2张
droptable#t
SQL Server2000中死锁经验总结第2张
总结
虽然不能完全避免死锁,但我们可以将死锁减至最少,并通过一定的方法来检测死锁

免责声明:文章转载自《SQL Server2000中死锁经验总结》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇CTF中的命令执行绕过Vista Sidebar Gadget (侧边栏小工具)开发教程 (3)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

spring中使用异步事件实现同步事务

在Spring中使用异步事件实现同步事务 结合Scala+Spring,我们将采取一个很简单的场景:下订单,然后发送一封电子邮件。 编制一个服务: @Service class OrderService @Autowired() (orderDao: OrderDao, mailNotifier: OrderMailNotifier) { @Transac...

php面试题2018

一 、PHP基础部分 1、PHP语言的一大优势是跨平台,什么是跨平台? PHP的运行环境最优搭配为Apache+MySQL+PHP,此运行环境可以在不同操作系统(例如windows、Linux等)上配置,不受操作系统的限制,所以叫跨平台 2、WEB开发中数据提交方式有几种?有什么区别?百度使用哪种方式? Get与post两种方式区别:(1)url可见性:g...

SQL Server中的锁类型及用法(转载)

一. 为什么要引入锁 多个用户同时对数据库的并发操作时会带来以下数据不一致的问题: 丢失更新 A,B两个用户读同一数据并进行修改,其中一个用户的修改结果破坏了另一个修改的结果,比如订票系统 脏读 A用户修改了数据,随后B用户又读出该数据,但A用户因为某些原因取消了对数据的修改,数据恢复原值,此时B得到的数据就与数据库内的数据产生了不一致 不可重复读 A用户...

MySQL5.6 新特性之GTID

1.mysql5.6在复制方面的新特性: (1).支持多线程复制:事实上是针对每个database开启相应的独立线程,即每个库有一个单独的(sql thread).针对这样的改进,如果我们想实现多线程复制,无疑要对现存的数据库结构进行重新设计,分库分表.对于压力都集中在个别database的,多线程并发复制特性就没有意义. (2).支持启用GTID,在配置...

c#调用存储过程两种方法

摘要 存储过程的调用在B/S系统中用的很多。传统的调用方法不仅速度慢,而且代码会随着存储过程的增多不断膨胀,难以维护。新的方法在一定程度上解决了这些问题。   关键词 ASP.NET;存储过程     在使用.NET的过程中,数据库访问是一个很重要的部分,特别是在B/S系统的构建过程中,数据库操作几乎成为了一个必不可少的操作。调用存储过程实现数据库操作使很...

spring源码 — 五、事务

spring提供了可配置、易扩展的事务处理框架,本文主要从一下几个方面说明spring事务的原理 基本概念 事务配置解析 事务处理过程 基本概念 事务隔离级别 在同时进行多个事务的时候,可能会出现脏读、不可重复读、幻读四种情况,数据库分别有四种隔离级别处理这些情况。Spring中TransactionDefinition定义了事务的隔离级别和传播属性,...