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

MSSQL
用Oracle和SQL Server数据库组合利弊分析
3个SQL视图搞定所有SqlServer数据库字典
使用SQL Server数据库的查询累计值
如何维护SQL Server的“交易日志”
SQL Server扩展存储过程实现远程备份与恢复
SQL Server 的存储过程
SQL Server 数据库嵌套子查询
如何使用SQL 事件探查器?
SQL Server 2008的新压缩特性
改进SQL Server数据库系统安全五步走
把SQL数据库部署到远程主机环境
SQL Server 2008综合数据可编程性
SQL Server 2005 数据维护实务
详细介绍微软SQL Server 2008
SQL Server数据库管理常用的SQL和T-SQL语句
从算法入手讲解SQL Server典例实现过程
ASP.NET连接Access和SQL Server数据库
SQL Server如何识别真实和自动创建的索引
SQL Server 2005数据转换服务的疑难解答
利用SQL Server 2005同义字缩短开发时间

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


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