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

MSSQL
SQL Server 中死锁产生的原因及解决办法
教你在SQL Server 2000数据库中使用分区
数据仓库基本报表制作过程中的SQL写法
自动定时重启sql server回收内存
轻松解决SQL Server 2005中的常见问题
用一个案例讲解SQL Server数据库恢复
安装SQL Server 2005时出现计数器错误
讲解SQL Server 2005数据库的同义词Bug
利用SQL语句对不同数据库进行高效果分页
三种数据库利用SQL语句进行高效果分页
数据库连接字符串的常见问题和解决方法
教你快速掌握一些方便易用的SQL语句
深入分析SQL Server的数据转换服务
系统默认的MySQL用户名消失的解决方法
SQL 2008邮件故障排除:发送测试电子邮件
SQL Server 2005日志文件损坏的处理方法
在SQL Server 2005数据库中进行错误捕捉
SQL Server查询速度慢原因及优化方法
加密SQL Anywhere 提升政府行业数据安全
Windows Server 2008之数据安全保护

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 221 ::
收藏到网摘: 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