当前位置: 首页 > 图文教程 > 数据库 > MSSQL > 分析及解决SQLServer死锁问题

MSSQL
修改自定义数据类型精度
SQL Server 2000之日志传送功能(1)
SQL Server 2000之日志传送功能(2)
建立安全的MSSQL SERVER启动账号
用T-SQL导入文件数据到SQL Server
SQL Server CHARINDEX和PATINDEX详解
如何同时对多个表或列操作
让数据库产生一张详细的日历表
用DTS导入多个文件数据到SQL Server中
SQL SERVER2000备份和恢复存储过程
将Excel中的数据导入到SQL Server 2000数据库中
SQL Server数据库文件恢复技术
SQL邮件自动应答
SQL Sever 2000的系统数据库和索引
SQLServer2000中UNION与UNION ALL的区别
用SQL语句来建立跟踪的问题
关于SQL Server 2000的安全配置
备份服务器端SQL SERVER数据库至本地目录
Sqlserver中的一些技巧
在SQL Server存储过程中执行DTS包

MSSQL 中的 分析及解决SQLServer死锁问题


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 171 ::
收藏到网摘: n/a

死锁,简而言之,两个或者多个trans,同时请求对方正在请求的某个对象,导致双方互相等待。简单的例子如下:
   trans1                                            trans2
   ------------------------------------------------------------------------
   1.IDBConnection.BeginTransaction   1.IDBConnection.BeginTransaction
   2.update table A                            2.update table B
   3.update table B                            3.update table A
   4.IDBConnection.Commit                4.IDBConnection.Commit
   那么,很容易看到,如果trans1和trans2,分别到达了step3,那么trans1会请求对于B的X锁,trans2会请求对于A的X锁,而二者的锁在step2上已经被对方分别持有了。由于得不到锁,后面的Commit无法执行,这样双方开始死锁。
   好,我们看一个简单的例子,来解释一下,应该如何解决死锁问题。
   -- Batch #1
   CREATE DATABASE deadlocktest
   GO
   USE deadlocktest
   SET NOCOUNT ON
   DBCC TRACEON (1222, -1)
   -- 在SQL2005中,增加了一个新的dbcc参数,就是1222,原来在2000下,我们知道,可以执行dbcc   
   --traceon(1204,3605,-1)看到所有的死锁信息。SqlServer 2005中,对于1204进行了增强,这就是1222。
   GO  
  
   IF OBJECT_ID ('t1') IS NOT NULL DROP TABLE t1
   IF OBJECT_ID ('p1') IS NOT NULL DROP PROC p1
   IF OBJECT_ID ('p2') IS NOT NULL DROP PROC p2
   GO
   CREATE TABLE t1 (c1 int, c2 int, c3 int, c4 char(5000))
   GO
   DECLARE @x int
   SET @x = 1
   WHILE (@x <= 1000) BEGIN
            INSERT INTO t1 VALUES (@x*2, @x*2, @x*2, @x*2)
            SET @x = @x + 1
   END
   GO
   CREATE CLUSTERED INDEX cidx ON t1 (c1)
   CREATE NONCLUSTERED INDEX idx1 ON t1 (c2)
   GO
   CREATE PROC p1 @p1 int AS SELECT c2, c3 FROM t1 WHERE c2 BETWEEN @p1 AND @p1+1
   GO
   CREATE PROC p2 @p1 int AS
            UPDATE t1 SET c2 = c2+1 WHERE c1 = @p1
            UPDATE t1 SET c2 = c2-1 WHERE c1 = @p1
   GO
   上述sql创建一个deadlock的示范数据库,插入了1000条数据,并在表t1上建立了c1列的聚集索引,和c2列的非聚集索引。另外创建了两个sp,分别是从t1中select数据和update数据。
   好,打开一个新的查询窗口,我们开始执行下面的query:
   -- Batch #2
   USE deadlocktest
   SET NOCOUNT ON
   WHILE (1=1) EXEC p2 4
   GO
   开始执行后,然后我们打开第三个查询窗口,执行下面的query:
   -- Batch #3
   USE deadlocktest
   SET NOCOUNT ON
   CREATE TABLE #t1 (c2 int, c3 int)
   GO
   WHILE (1=1) BEGIN
             INSERT INTO #t1 EXEC p1 4
             TRUNCATE TABLE #t1