sql死锁进程
A. sql SERVER进程锁死后,只能重启SQL SERVER才恢复正常
这肆宴种可以按照提示中的进行数据库检查,如数据库文件有损坏,则需要进行修复,修裂丛银复结果可能会
存在丢数据的情况,但修复后回郑帆解决掉每次都报错的情况。
B. 如何处理SQL Server死锁问题
死锁,简而言之,两个或者多个trans,同时请求对方正在请求的某个对象,导致双方互相等待。简单的例子如下:x0dx0a trans1 trans2x0dx0a ------------------------------------------------------------------------x0dx0a 1.IDBConnection.BeginTransaction 1.IDBConnection.BeginTransactionx0dx0a 2.update table A 2.update table Bx0dx0a 3.update table B 3.update table Ax0dx0a 4.IDBConnection.Commit 4.IDBConnection.Commit x0dx0a 那么,很容易看到,如果trans1和trans2,分别到达了step3,那么trans1会请求对于B的X锁,trans2会请求对于A的X锁,而二者的锁在step2上已经被对方分别持有了。由于得不到锁,后面的Commit无法执行,这样双方开始死锁。x0dx0a 好,我们看一个简单的例子,来解释一下,应该如何解决死锁问题。x0dx0a -- Batch #1x0dx0a CREATE DATABASE deadlocktestx0dx0a GOx0dx0a USE deadlocktestx0dx0a SET NOCOUNT ONx0dx0a DBCC TRACEON (1222, -1)x0dx0a -- 在SQL2005中,增加了一个新的dbcc参数,就是1222,原来在2000下,我们知道,可以执行dbcc x0dx0a --traceon(1204,3605,-1)看到所有的死锁信息。SqlServer 2005中,对于1204进行了增强,这就是1222。x0dx0a GO x0dx0a x0dx0a IF OBJECT_ID ('t1') IS NOT NULL DROP TABLE t1x0dx0a IF OBJECT_ID ('p1') IS NOT NULL DROP PROC p1x0dx0a IF OBJECT_ID ('p2') IS NOT NULL DROP PROC p2x0dx0a GOx0dx0a CREATE TABLE t1 (c1 int, c2 int, c3 int, c4 char(5000)) x0dx0a GOx0dx0a DECLARE @x intx0dx0a SET @x = 1x0dx0a WHILE (@x <= 1000) BEGINx0dx0a INSERT INTO t1 VALUES (@x*2, @x*2, @x*2, @x*2)x0dx0a SET @x = @x + 1x0dx0a ENDx0dx0a GOx0dx0a CREATE CLUSTERED INDEX cidx ON t1 (c1)x0dx0a CREATE NONCLUSTERED INDEX idx1 ON t1 (c2)x0dx0a GOx0dx0a CREATE PROC p1 @p1 int AS SELECT c2, c3 FROM t1 WHERE c2 BETWEEN @p1 AND @p1+1x0dx0a GOx0dx0a CREATE PROC p2 @p1 int ASx0dx0a UPDATE t1 SET c2 = c2+1 WHERE c1 = @p1x0dx0a UPDATE t1 SET c2 = c2-1 WHERE c1 = @p1x0dx0a GOx0dx0a 上述sql创建一个deadlock的示范数据库,插入了1000条数据,并在表t1上建立了c1列的聚集索引,和c2列的非聚集索引。另外创建了两个sp,分别是从t1中select数据和update数据。 x0dx0a 好,打开一个新的查询窗口,我们开始执行下面的query:x0dx0a -- Batch #2x0dx0a USE deadlocktestx0dx0a SET NOCOUNT ONx0dx0a WHILE (1=1) EXEC p2 4x0dx0a GOx0dx0a 开始执行后,然后我们打开第三个查询窗口,执行下面的query:x0dx0a -- Batch #3x0dx0a USE deadlocktestx0dx0a SET NOCOUNT ONx0dx0a CREATE TABLE #t1 (c2 int, c3 int)x0dx0a GOx0dx0a WHILE (1=1) BEGINx0dx0a INSERT INTO #t1 EXEC p1 4x0dx0a TRUNCATE TABLE #t1x0dx0a ENDx0dx0a GOx0dx0a 开始执行,哈哈,很快,我们看到了这样的错误信息:x0dx0a Msg 1205, Level 13, State 51, Procere p1, Line 4x0dx0a Transaction (Process ID 54) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.x0dx0a spid54发现了死锁。 x0dx0a 那么,我们该如何解决它?x0dx0a 在SqlServer 2005中,我们可以这么做:x0dx0a 1.在trans3的窗口中,选择EXEC p1 4,然后right click,看到了菜单了吗?选择Analyse Query in Database Engine Tuning Advisor。x0dx0a 2.注意右面的窗口中,wordload有三个选择:负载文件、表、查询语句,因为我们选择了查询语句的方式,所以就不需要修改这个radio option了。x0dx0a 3.点左上角的Start Analysis按钮x0dx0a 4.抽根烟,回来后看结果吧!出现了一个分析结果窗口,其中,在Index Recommendations中,我们发现了一条信息:大意是,在表t1上增加一个非聚集索引索引:t2+t1。x0dx0a 5.在当前窗口的上方菜单上,选择Action菜单,选择Apply Recommendations,系统会自动创建这个索引。x0dx0a 重新运行batch #3,呵呵,死锁没有了。x0dx0a 这种方式,我们可以解决大部分的Sql Server死锁问题。那么,发生这个死锁的根本原因是什么呢?为什么增加一个non clustered index,问题就解决了呢? 这次,我们分析一下,为什么会死锁呢?再回顾一下两个sp的写法:x0dx0a CREATE PROC p1 @p1 int AS x0dx0a SELECT c2, c3 FROM t1 WHERE c2 BETWEEN @p1 AND @p1+1 x0dx0a GOx0dx0a CREATE PROC p2 @p1 int ASx0dx0a UPDATE t1 SET c2 = c2+1 WHERE c1 = @p1x0dx0a UPDATE t1 SET c2 = c2-1 WHERE c1 = @p1x0dx0a GOx0dx0a 很奇怪吧!p1没有insert,没有delete,没有update,只是一个select,p2才是update。这个和我们前面说过的,trans1里面updata A,update B;trans2里面upate B,update A,根本不贴边啊!x0dx0a 那么,什么导致了死锁?x0dx0a 需要从事件日志中,看sql的死锁信息:x0dx0a Spid X is running this query (line 2 of proc [p1], inputbuffer “? EXEC p1 4 ?”): x0dx0a SELECT c2, c3 FROM t1 WHERE c2 BETWEEN @p1 AND @p1+1x0dx0a Spid Y is running this query (line 2 of proc [p2], inputbuffer “EXEC p2 4”): x0dx0a UPDATE t1 SET c2 = c2+1 WHERE c1 = @p1x0dx0a x0dx0a The SELECT is waiting for a Shared KEY lock on index t1.cidx. The UPDATE holds a conflicting X lock. x0dx0a The UPDATE is waiting for an eXclusive KEY lock on index t1.idx1. The SELECT holds a conflicting S lock.x0dx0a 首先,我们看看p1的执行计划。怎么看呢?可以执行set statistics profile on,这句就可以了。下面是p1的执行计划x0dx0a SELECT c2, c3 FROM t1 WHERE c2 BETWEEN @p1 AND @p1+1x0dx0a |--Nested Loops(Inner Join, OUTER REFERENCES:([Uniq1002], [t1].[c1]))x0dx0a |--Index Seek(OBJECT:([t1].[idx1]), SEEK:([t1].[c2] >= [@p1] AND [t1].[c2] <= [@p1]+(1)) ORDERED FORWARD)x0dx0a |--Clustered Index Seek(OBJECT:([t1].[cidx]), SEEK:([t1].[c1]=[t1].[c1] AND [Uniq1002]=[Uniq1002]) LOOKUP ORDERED FORWARD)x0dx0a 我们看到了一个nested loops,第一行,利用索引t1.c2来进行seek,seek出来的那个rowid,在第二行中,用来通过聚集索引来查找整行的数据。这是什么?就是bookmark lookup啊!为什么?因为我们需要的c2、c3不能完全的被索引t1.c1带出来,所以需要书签查找。 x0dx0a 好,我们接着看p2的执行计划。x0dx0a UPDATE t1 SET c2 = c2+1 WHERE c1 = @p1x0dx0a |--Clustered Index Update(OBJECT:([t1].[cidx]), OBJECT:([t1].[idx1]), SET:([t1].[c2] = [Expr1004]))x0dx0a |--Compute Scalar(DEFINE:([Expr1013]=[Expr1013]))x0dx0a |--Compute Scalar(DEFINE:([Expr1004]=[t1].[c2]+(1), [Expr1013]=CASE WHEN CASE WHEN ...x0dx0a |--Top(ROWCOUNT est 0)x0dx0a |--Clustered Index Seek(OBJECT:([t1].[cidx]), SEEK:([t1].[c1]=[@p1]) ORDERED FORWARD) x0dx0a 通过聚集索引的seek找到了一行,然后开始更新。这里注意的是,update的时候,它会申请一个针对clustered index的X锁的。x0dx0a 实际上到这里,我们就明白了为什么update会对select产生死锁。update的时候,会申请一个针对clustered index的X锁,这样就阻塞住了(注意,不是死锁!)select里面最后的那个clustered index seek。死锁的另一半在哪里呢?注意我们的select语句,c2存在于索引idx1中,c1是一个聚集索引cidx。问题就在这里!我们在p2中更新了c2这个值,所以sqlserver会自动更新包含c2列的非聚集索引:idx1。而idx1在哪里?就在我们刚才的select语句中。而对这个索引列的更改,意味着索引集合的某个行或者某些行,需要重新排列,而重新排列,需要一个X锁。x0dx0a SO???,问题就这样被发现了。x0dx0a 总结一下,就是说,某个query使用非聚集索引来select数据,那么它会在非聚集索引上持有一个S锁。当有一些select的列不在该索引上,它需要根据rowid找到对应的聚集索引的那行,然后找到其他数据。而此时,第二个的查询中,update正在聚集索引上忙乎:定位、加锁、修改等。但因为正在修改的某个列,是另外一个非聚集索引的某个列,所以此时,它需要同时更改那个非聚集索引的信息,这就需要在那个非聚集索引上,加第二个X锁。select开始等待update的X锁,update开始等待select的S锁,死锁,就这样发生鸟。 x0dx0a 那么,为什么我们增加了一个非聚集索引,死锁就消失鸟?我们看一下,按照上文中自动增加的索引之后的执行计划:x0dx0a SELECT c2, c3 FROM t1 WHERE c2 BETWEEN @p1 AND @p1+1x0dx0a |--Index Seek(OBJECT:([deadlocktest].[dbo].[t1].[_dta_index_t1_7_2073058421__K2_K1_3]), SEEK:([deadlocktest].[dbo].[t1].[c2] >= [@p1] AND [deadlocktest].[dbo].[t1].[c2] <= [@p1]+(1)) ORDERED FORWARD)x0dx0a 哦,对于clustered index的需求没有了,因为增加的覆盖索引已经足够把所有的信息都select出来。就这么简单。x0dx0a 实际上,在sqlserver 2005中,如果用profiler来抓eventid:1222,那么会出现一个死锁的图,很直观的说。x0dx0a 下面的方法,有助于将死锁减至最少(详细情况,请看SQLServer联机帮助,搜索:将死锁减至最少即可。x0dx0a按同一顺序访问对象。 x0dx0a避免事务中的用户交互。 x0dx0a保持事务简短并处于一个批处理中。 x0dx0a使用较低的隔离级别。 x0dx0a使用基于行版本控制的隔离级别。 x0dx0a将 READ_COMMITTED_SNAPSHOT 数据库选项设置为 ON,使得已提交读事务使用行版本控制。 x0dx0a使用快照隔离。x0dx0a使用绑定连接。
C. SQL 进程死锁
首先,需要把你的AutoCommit=TRUE,然后,这是一个编程习惯问题,在pb中,对于数据窗口的操作,首先设置数据窗口的提交方式,我一直
采用 key columns,use
update,然后记得在每次连接完成后,记得及时释放,譬如,在retrieve完成后,记得及时利用resetupdate()清除数据状态,然后,
再每次数据库更新,也就是update()后,记得利用
ll_num1=.update()
if ll_num=1 then
commit;
dw_free.resetupdate( )
else
rollback;
messagebox("提示!","数据保存失败! ")
end if
以上说法我不赞同:
1、首先AutoCommit=TRUE,以后执行delete,update,insert语句都相当执行了commit,如果是把几个SQL语句当作是一个完整的事务,要不整
体成功提交,要不rollback,这就写就不会得到正确的结果。
2、其次key columns,use update,要具体情况具体使用,这种形式的并发性最差,适合对数据的并发性要求不高的场合。
3、再次程序的死锁原因是多方面的,上述两个方面只是其中的原因罢了,具体情况具体分析,例如数据尽快提交、建立合理的索引、合理的SQ
L语句、避免交叉事务、对于数据量庞大的表,应及时转移到历史库,我想可以很大程度上避免死锁。
以上愚见,欢迎拍砖。
在MSSQL控制台中,管理-当前活动-锁/进程ID看看是那几个进程在死锁,然后在进程信息中将这些死锁的进程杀死/
对查询进行优化
也建议检查:外键建立索引,如果上索引,再调试下网络
对外键建索引可以缓解这个问题。
如在商品字典和销售明细表中,销售明细表中商品编号是外键,如果在销售明细表的商品编号上没有索引,update商品字典会造成销售明细表
整表锁表。
解决Sybase数据库死锁的方法
人民银行吉林市中心支行科技处 刘志明
在联机事务处理(OLTP)的数据库应用系统中,多用户、多任务的并发性是系统最重要的技术指标之一。为了提高并发性,目前大部分RDBMS都采
用加锁技术。然而由于现实环境的复杂性,使用加锁技术又不可避免地产生了死锁问题。因此如何合理有效地使用加锁技术,最小化死锁是开
发联机事务处理系统的关键。
死锁产生的原因
在联机事务处理系统中,造成死机主要有两方面原因。一方面,由于多用户、多任务的并发性和事务的完整性要求,当多个事务处理对多个资
源同时访问时,若双方已锁定一部分资源但也都需要对方已锁定的资源时,无法在有限的时间内完全获得所需的资源,就会处于无限的等待状
态,从而造成其对资源需求的死锁。
另一方面,数据库本身加锁机制的实现方法不同,各数据库系统也会产生其特殊的死锁情况。如在Sybase SQL Server 11中,最小锁为2K一页
的加锁方法,而非行级锁。如果某张表的记录数少且记录的长度较短(即记录密度高,如应用系统中的系统配置表或系统参数表就属于此类表)
,被访问的频率高,就容易在该页上产生死锁。
几种死锁情况及解决方法
清算应用系统中,容易发生死锁的几种情况如下:
● 不同的存储过程、触发器、动态SQL语句段按照不同的顺序同时访问多张表;
● 在交换期间添加记录频繁的表,但在该表上使用了非群集索引(non-clustered);
● 表中的记录少,且单条记录较短,被访问的频率较高;
● 整张表被访问的频率高(如代码对照表的查询等)。
以上死锁情况的对应处理方法如下:
● 在系统实现时应规定所有存储过程、触发器、动态SQL语句段中,对多张表的操作总是使用同一顺序。如:有两个存储过程proc1、proc2,
都需要访问三张表zltab、z2tab和z3tab,如果proc1按照zltab、z2tab和z3tab的顺序进行访问,那么,proc2也应该按照以上顺序访问这三张
表。
● 对在交换期间添加记录频繁的表,使用群集索引(clustered),以减少多个用户添加记录到该表的最后一页上,在表尾产生热点,造成死锁
。这类表多为往来账的流水表,其特点是在交换期间需要在表尾追加大量的记录,并且对已添加的记录不做或较少做删除操作。
● 对单张表中记录数不太多,且在交换期间select或updata较频繁的表可使用设置每页最大行的办法,减少数据在表中存放的密度,模拟行级
锁,减少在该表上死锁情况的发生。这类表多为信息繁杂且记录条数少的表。
如:系统配置表或系统参数表。在定义该表时添加如下语句:
with max_rows_per_page=1
● 在存储过程、触发器、动态SQL语句段中,若对某些整张表select操作较频繁,则可能在该表上与其他访问该表的用户产生死锁。对于检查
账号是否存在,但被检查的字段在检查期间不会被更新等非关键语句,可以采用在select命令中使用at isolation read uncommitted子句的方
法解决。该方法实际上降低了select语句对整张表的锁级别,提高了其他用户对该表操作的并发性。在系统高负荷运行时,该方法的效果尤为
显着。
例如:
select*from titles at isolation read uncommitted
● 对流水号一类的顺序数生成器字段,可以先执行updata流水号字段+1,然后再执行select获取流水号的方法进行操作。
小结
笔者对同城清算系统进行压力测试时,分别对采用上述优化方法和不采用优化方法的两套系统进行测试。在其他条件相同的情况下,相同业务
笔数、相同时间内,死锁发生的情况如下:
采用优化方法的系统: 0次/万笔业务;
不采用优化方法的系统:50~200次/万笔业务。
所以,使用上述优化方法后,特别是在系统高负荷运行时效果尤为显着。总之,在设计、开发数据库应用系统,尤其是OLTP系统时,应该根据
应用系统的具体情况,依据上述原则对系统分别优化,为开发一套高效、可靠的应用系统打下良好的基础。
经验:
1:前台问题:检视代码查看事物是否被提交或回滚。
2:后台问题:有时候由于处理的问题复杂度高。数据库日志空间已满或不够
导致事物未能提交。UNIX下的SYBAE就是典型的一例。解决办法各数据库厂商有更详细的说明。
虽然我从9转到10遇到了好多问题,也浪费了好几天的时间,但到了现在,我真觉得10比9好。
10没有了MSSQL专用接口,用的是OLEDB接口,用这个接口一定要注意一个问题是表死锁的事!
网上讲的连接方式都是天下一大抄。
用OLEDB要加上 SQLCA.Lock = "RC",
不然连查询也会死锁。
另个一个就是10写的软件不再乱码了,我在繁体写的软件在简体下运行不乱码,反之也可以。
第三就是编译速度明显快很多。
第四就是编译的时候有了XP样式皮肤,感觉漂亮多了。
编程要是要养成好习惯,在sql语句insert和update之后,要及时commit,数据窗口update()后也要及时commit;
阻塞是因为多个进程对同一一个资源的访问冲突,当一个进程排它访问一个资源时(从进入事务到事务结束为止),当有其他进程需要访问同
样的资源时,即造成阻塞(根据锁的级别和粒度设置);
在实际应用中阻塞可能因为事务没有提交或者网络速度太慢或者大容量的数据查询等都可能会造成阻塞。
阻塞可以通过sp_who 系统存储过程进行查看,执行sp_who 后查看所有blk不等于
0的进程ID(SPID),直到找到SPID在blk列出现,但当前spid 的blk列 =0 即它就是阻塞的源头。
最简单的办法可用 kill spid(源头进程的SPID值),同时结合sp_lock过程可查看到当前进程的加锁情况(如锁的类型被锁的对象)
最后最重要的是要根据 在查询到源头后,使用 DBCC INPUTBUFFER (spid)查看最后一次提交的内容,即可找到因为事务没有提交造成的阻塞(
一般不能使用 AutoCommit=True,因为大部分MIS程序需要使用批提交,来保证数据的完成性)
http://www.51onnet.com/bbs/forumdisplay.php?f=6
你可能平时编程时没有注意。在 SQLCA(Transaction)默认情况下 AutoCommit = false(不自动提交)。在同一事务中,如果不提交事务,
可以SELECT、Retrieve,但其它事务(其它计算机的应用程序连接数据库的事务)就不能。所以导致死锁,而在单机开发环境看不出来。
你需要在所有的 UPDATE、DELETE 的SQL语句后面,或者数据窗口的Update函数调用之后执行 COMMIT 或 ROLLBACK
死锁可能存在的原因及解决办法
一次偶然的机会在论坛上看到一个关于死锁(其实是阻塞)的帖子,于是把自己的一个小东东拿出来和大家分享,想不到很多人都遇到过这个
问题。
其实解锁并不是根本的解决办法,感觉我自己有点误导大家了,于是有了下面的内容,希望大家能根据自己的应用找出根源,而不是解锁:
阻塞可能存在的原因及解决方法:
1、事务未提交
这是造成阻塞最常见的原因,因为PB默认是自动启动事务的,如果你执行了 update,delete ,insert 语句,不执行Commit 则会出现阻塞(
不建议采用自动提交事务的方式,原因在上一帖中交代过),解决的办法很简单,查找到所有的修改数据命令(U、I、D)查看是否正常提交,找
到后加入Commit即可;
2、SQL SERVER 没有正常安装SP3
对于代码正常的用户,仍然出现阻塞,则需要检查你机器的补丁,特别是WIN2003的机器不安装补丁,1433都不能监听;如果没有安装补丁
即可(我原来就是被这种情况害过)
3、当然可能你会告诉我,代码也没有问题,补丁也装了,仍然出现可能就需要查看你的机器的CPU和内存的使用率(运行taskmgr),SQL
SERVER 的机器峰值状态可能出现阻塞,解决的办法就是出钱:升级服务器;
4、复杂的查询或者大容量查询,比如在查询中使用多个表的联合查询,或者使用 in ,not in 等语句,是非常耗时的,这种解决的办法稍微复
杂点,需要根据你的应用修改SQL 语句,优化SQL 效率,关于SQL 优化是另外一个复杂的话题,本人也学习中...
能想起的好象就这些了,可能不是很完善,希望有人能补充!
你可能平时编程时没有注意。在 SQLCA(Transaction)默认情况下 AutoCommit = false(不自动提交)。在同一事务中,如果不提交事务,
可以SELECT、Retrieve,但其它事务(其它计算机的应用程序连接数据库的事务)就不能。所以导致死锁,而在单机开发环境看不出来。
你需要在所有的 UPDATE、DELETE 的SQL语句后面,或者数据窗口的Update函数调用之后执行 COMMIT 或 ROLLBACK
补充一点,除了在执行了Update,Delete,Insert需要及时Commit外,在SQL Server中由于使用一个Tempdb的数据库,这个数据库是对所有用户共享
的,当使用了统计类型的SQL函数如:sum,count等,SQL Server会自动使用Tempdb进行暂存统计数据,这样很容易造成Tempdb被锁住,所以在读取了
一个很复杂Store Procere或创建过临时表后应进行commit,以便释放Tempdb资源,在retrieved事件中加commit是一个解决办法,特别是在读取
报表后更应加,一般报表的Store Procere都比较复杂,在程序中内嵌了SQL光标来读取数据后也要加commit,我增经试过被锁住,找了很久才知
D. SQL的死锁怎么查进程
可以用 sp_who查询碰含死锁,在查询的结果里有个blk字段,如果这个字段显示为 0 就是正常闷拆,大于蚂吵枣0 就是我们说的死锁!
E. sql进程死锁
你的两个问题的回答是肯定的。
rs.Open是拍伍单纯打开结果集,是读操作,一般不会死锁;
另外一个问题,Update的速度是袭改或比rs.Open要快,因为Update的数据传递量少,而且基本上是单向操作,就是发送指令到数据库服务器,然后在服务器侧歼埋运行;而rs.Open不但要发送查询指令到数据库服务器,还要把产生的结果集返回到客户端,网络流量大,需要的时间要多。
F. 如何查找SQL2008死锁进程及对应SQL
-- 查询死锁
select
request_session_id spid,
OBJECT_NAME(resource_associated_entity_id) tableName
from
sys.dm_tran_locks
where
resource_type='OBJECT'
--杀死死锁腔磨进程
kill 354
创造死锁条件
开两个查询窗口
BEGIN TRANSACTION--开始事务
update job set creator='00000'肆耐 where id='001'
WAITFOR DELAY '02:00';
select * from job where id='001'裂圆春
G. sql server死锁的进程怎么处理
怎么解除SQL Server死锁的问题?SQL Server死锁是我们经常会碰到的问题,下面就为您介绍如何查询SQL Server死锁,希望对您学习SQL Server死锁方面能有所帮助。
SQL Server死锁的查询方法: exec master.dbo.p_lockinfo 0,0 ---显示死锁的进程,不显示正常的进程 exec master.dbo.p_lockinfo 1,0 ---杀死死锁的进程,不显示正常的进程.
SQL Server死锁的解除方法: Create proc p_lockinfo @kill_lock_spid bit=1, --是扒派否杀掉死锁的进程,1 杀掉, 0 仅显示 @show_spid_if_nolock bit=1 --如果没有死锁的进程,是否显示正常进程信息,1 显示,0 不显示 as 春培贺 declare @count int,@s nvarchar(1000),@i int select id=identity(int,1,1),标志, 进程ID=spid,线程ID=kpid,块进程ID=blocked,数据库ID=dbid,
数据库名=db_name(dbid),用户ID=uid,用户名=loginame,累计CPU时间=cpu, 登陆时间=login_time,打开事务数=open_tran, 进程状态=status, 工作站名=hostname,应用程序名=program_name,工作站进程ID=hostprocess, 域名=nt_domain,网卡地址=net_address into #t from( select 标志='死锁的进程', spid,kpid,a.blocked,dbid,uid,loginame,cpu,login_time,open_tran, status,hostname,program_name,hostprocess,nt_domain,net_address,
s1=a.spid,s2=0 from mastersysprocesses a join ( select blocked from mastersysprocesses group by blocked )b on a.spid=b.blocked where a.blocked=0 union all select '|_牺中锋牲品_>', spid,kpid,blocked,dbid,uid,loginame,cpu,login_time,open_tran, status,hostname,program_name,hostprocess,nt_domain,net_address, s1=blocked,s2=1 from mastersysprocesses a where blocked<>0 )a order by s1,s2 select @count=@@rowcount,@i=1 if @count=0 and @show_spid_if_nolock=1 begin insert #t select 标志='正常的进程', spid,kpid,blocked,dbid,db_name(dbid),uid,loginame,cpu,login_time, open_tran,status,hostname,program_name,hostprocess,nt_domain,net_address from mastersysprocesses set @count=@@rowcount end if @count>0 begin create table #t1(id int identity(1,1),a nvarchar(30),b Int,EventInfo nvarchar(255)) if @kill_lock_spid=1 begin declare @spid varchar(10),@标志 varchar(10) while @i<=@ count begin select @spid=进程ID,@标志=标志 from #t whereid=@ i insert #t1 exec('dbcc inputbuffer(')') if @标志='死锁的进程' exec('kill'+@ spid) set @i=@i+1 end end else while @i<=@ count begin select @s='dbcc inputbuffer('+cast(进程ID as varchar)+')' from #t whereid=@ i insert #t1 exec(@s) set @i=@i+1 end select a.*,进程的SQL语句=b.EventInfo from #t a join #t1 b on a.id=b.id end