一个诡异的SQL Server数据库查询阻塞分析

客户发过来关于一个很诡异的SQL Server 数据库阻塞的问题,发现了查询和查询语句之间发生了阻塞,希望我帮忙分析原因。
 
原因是:blocking-process 之前的语句导致阻塞的发生之后又执行了其他的语句,显示的是后来执行的语句和 blocked-process 发生了阻塞
 
【背景】
 
背景是这样的,一周前,我告诉了客户一个方法来跟踪SQL Server中的阻塞:
1)开启数据库的阻塞报告阀值为5秒:
Exec sp_configure
Exec sp_configure 'show advanced options',1
Reconfigure With override
Exec sp_configure 'blocked process threshold (s)',5
Reconfigure With override
2)使用Profiler跟踪阻塞:
  • 基于TSQL_Duration建立一个跟踪模版
  • 增加Errors and Warnings事件类别下的Blocked Process Report事件
  • 使用新建的跟踪模版建立跟踪,保存结果为*.trc文件
3)客户跟踪到了不少阻塞时间,但是其中有一个很诡异的阻塞,出现了查询和查询语句的阻塞,结果类似如下:
<blocked-process-report>
 <blocked-process>
  <process id="process32f8e8" taskpriority="0" logused="0" waitresource="KEY: 9:72057594039697408 (010086470766)" waittime="12598" ownerId="18641" transactionname="SELECT" lasttranstarted="2009-08-17T18:06:01.693" XDES="0x58bdde8" lockMode="S" schedulerid="2" kpid="5688" status="suspended" spid="53" sbid="0" ecid="0" priority="0" trancount="0" lastbatchstarted="2009-08-17T18:06:01.693" lastbatchcompleted="2009-08-17T18:06:01.693" clientapp="Microsoft SQL Server Management Studio - 查询" hostname="FRANK-W7" hostpid="1828" loginname="Frank-W7\Frank" isolationlevel="read committed (2)" xactid="18641" currentdb="9" lockTimeout="4294967295" clientoption1="671090784" clientoption2="390200">
   <executionStack>
    <frame line="2" stmtstart="4" sqlhandle="0x02000000183ec32ca83703ef10ad2127bc6fc77e1aba4203"/>
   </executionStack>
   <inputbuf>
Select * from 产品
--rollback   </inputbuf>
  </process>
 </blocked-process>
 <blocking-process>
  <process status="sleeping" spid="55" sbid="0" ecid="0" priority="0" trancount="1" lastbatchstarted="2009-08-17T18:06:13.923" lastbatchcompleted="2009-08-17T18:06:13.923" clientapp="Microsoft SQL Server Management Studio - 查询" hostname="FRANK-W7" hostpid="1828" loginname="Frank-W7\Frank" isolationlevel="read committed (2)" xactid="18634" currentdb="9" lockTimeout="4294967295" clientoption1="671090784" clientoption2="390200">
   <executionStack/>
   <inputbuf>
select * from 产品 where 产品Id=1   </inputbuf>
  </process>
 </blocking-process>
</blocked-process-report>
通常查询和查询在正常情况,没事使用锁提示的时候是不会发生阻塞的。但是跟踪的结果却出现了不合逻辑的现象。
 
 
【分析】
我重现了这个问题,找到了问题:
 
1.开启两个会话和Profiler进行跟踪:
会话一, 只执行第一部分,即前两行代码:
--1
Begin Tran
Update 产品  Set 单价 =111 where 产品ID =1
--2
select * from 产品 where 产品Id=1
会话二:
Select * from 产品
 
2.由于阻塞阀值设置为5秒,5秒之后,Profiler跟踪到了第一个阻塞,显示发生阻塞的是:
Begin Tran
Update 产品  Set 单价 =111 where 产品ID =1
Select * from 产品
3.接下来执行了会话一中的第2句话,即:select * from 产品 where 产品Id=1
 
4.Profiler很快跟踪到了第二个阻塞,即前面的blocked-process-report,显示发生阻塞的是:
select * from 产品 where 产品Id=1
Select * from 产品
【结论】
由此可见,比较郁闷的是,Profiler 跟踪到得阻塞,只显示的发生阻塞的事务中的最后一句话,这其实不是导致阻塞的根本原因。而查询和查询正常情况下是不会出现阻塞的。

你可能感兴趣的:(数据库,职场,阻塞,休闲)