今天在sql server 锁报表中,查到表A,被表B的进程阻塞,很是怀疑是不是有问题,在测试环境自己测试如下:
sql
<blocked-process-report monitorLoop="15930">
<blocked-process>
<process id="process2a76206f088" taskpriority="0" logused="0" waitresource="KEY: 7:72057594042712064 (8194443284a0)" waittime="31677" ownerId=" ver Management Studio - 查询" hostname="xx" hostpid="16952" loginname="xx" isolationlevel="read committed (2)" xactid="57
<executionStack>
<frame line="2" stmtstart="70" stmtend="158" sqlhandle="0x02000000c7fda51c492cd5728447ae24bb54967afddb674300000000000000000000000000000000000
<frame line="2" stmtstart="4" stmtend="92" sqlhandle="0x02000000e9e5811cb0c129bc2a0e0e16f93f315c7289ff0e0000000000000000000000000000000000000
</executionStack>
<inputbuf>
update [dbo].[t01]
set a='a02'
where c='b' </inputbuf>
</process>
</blocked-process>
<blocking-process>
<process status="suspended" 《生产环境中的status 是sleeping》 waittime="34349" spid="57" sbid="0" ecid="0" priority="0" trancount="1" lastbatchstarted="2026-01-29T09:30:36.197"
<executionStack>
<frame line="10" stmtstart="228" stmtend="288" sqlhandle="0x020000003cf18f030ea3e7bcae65b7f0824a363107a1382e0000000000000000000000000000000000000000" />
</executionStack>
<inputbuf>
begin tran
update [dbo].[t01]
set a='a01'
where c is null
select * from [dbo].[t01]
where id=1
WAITFOR DELAY '00:00:50';
commit;
select * from [dbo].[t01] </inputbuf>
</process>
</blocking-process>
</blocked-process-report>
dbo\].\[t01\] 表的更新在where 条件中的字段是没有索引的,如果更新,无论走哪个索引的执行计划,都会有FULL表的锁,这个时候再执行其他语句,不提交事务,就会一直处于等待状态,( 《生产环境中的status 是sleeping》我这里的是 suspended ,有可能需要用应用的客户端程序才可以复现出来) 而另外一个事务要更新表 \[dbo\].\[t01\] ,就会一直等待,就会出现锁的情况。 分析应该是如下情况: 第一个进程修改数据没有提交,一直在等待,在阻塞的进程报表里看看就会出现表A,被表B的进程阻塞的情况,有可能该进程的前一条的更新语句是更新语句, 并且where条件是没有索引的,会锁全表。 解决方案: 建议在where条件增加索引,即使where条件是相同的列,不修改相同的记录,是不会出现U(更新)锁的