信息化 频道

使用SQL Server Profiler监视分析死锁

  【IT168技术】在两个或多个SQL Server进程中,每一个进程锁定了其他进程试图锁定的资源,就会出现死锁,例如:

  进程process1对table1持有1个排它锁(X),同时process1对table2请求1个排它锁(X),

  进程process2对table2持有1个排它锁(X),同时process2对table1请求1个排它锁(X)

  类似这种情况,就会出现死锁,除非当某个外部进程断开死锁,否则死锁中的两个事务都将无限期等待下去。

  Microsoft SQL Server 数据库引擎死锁监视器定期检查陷入死锁的任务。

  如果监视器检测到循环依赖关系,将选择其中一个任务作为牺牲品(通常是选择占资源比较小的进程作为牺牲品),然后终止其事务并提示错误1205。

  这里我们通过SQL Server Profiler来监视分析死锁的发生过程,那样我们就会深刻理解死锁的成因。

  创建测试表

  在 Microsoft SQL Server Management Studio上,新建一个查询,写创建表DealLockTest_1 & DealLockTest_2两个表:

  脚本:

use Test

--创建分析死锁使用到的两个表DealLockTest_1 & DealLockTest_2
go
Set Nocount On    
Go
if object_id('DealLockTest_1') Is Not Null
    Drop Table DealLockTest_1
go
Create Table DealLockTest_1
(
    ID
int Identity(1,1) Primary Key,
    Name nvarchar(
512)
)

if object_id('DealLockTest_2') Is Not Null
    Drop Table DealLockTest_2
go
Create Table DealLockTest_2
(
    ID
int Identity(1,1) Primary Key,
    Name nvarchar(
512)
)

Go

--插入一些测试数据
Insert Into DealLockTest_1(Name)
    Select name From sys.all_objects

    
Insert Into DealLockTest_2(Name)
    Select name From sys.all_objects
Go

  创建好表和插入测试数据后,先执行脚本代码(因为我们不需要跟踪该代码),紧接着,我们就模拟两个会话,一个会话里面包含一个事务。这里我们就新建两个查询,其中第一个会话,是更新DealLockTest_1表后,等待5秒钟,更新DealLocktest_2.

  代码写好后,我们先不要执行代码,接下来就写第二个会话代码; 第二个会话更新表的顺序,刚好与第一个会话相反,是更新DealLockTest_2表后,等待5秒钟,更新DealLocktest_1.

  第二个会话代码,也先不要执行。

  启动SQL Server Profiler,创建Trace(跟踪).

  启动SQL Server Profiler工具(在Microsoft SQL Server Management Studio的工具菜单上就发现它),创建一个Trace,Trace属性选择主要是包含:

  Deadlock graph

  Lock: Deadlock

  Lock: Deadlock Chain

  RPC:Completed

  SP:StmtCompleted

  SQL:BatchCompleted

  SQL:BatchStarting

         点执行按钮,启动Trace。

  执行测试代码&监视死锁

  转到 Microsoft SQL Server Management Studio界面,执行第一个会话&第二个会话的代码,稍稍等待5秒钟,我们就会发现其中一个会话收到报错消息

  我们再切换到SQL Server Profiler界面,就能发现SQL Server Profiler收到执行脚本过程发生死锁的信息。

  OK,这里就先停止SQL Server Profiler上的“暂停跟踪” Or "停止跟踪"按钮,下面我们具体分析死锁发生过程。

0
相关文章