SQL Server阻塞树疑问:SELECT会话115为何被103而非97阻塞?
阻塞场景排查疑问
阻塞树信息
| SPID | Query (Text) | Wait Type | Blocked By |
|---|---|---|---|
| 97 | <?query -- select * from blockthis where subid =5 --?> | NULL | NULL |
| 103 | <?query -- SELECT * FROM [blockthis] WHERE [subid]=@1 --?> | (9411ms) LCK_M_S | 97 |
| 115 | <?query -- SELECT [id] FROM [blockthis] WHERE [subid]=@1 --?> | (5720ms) LCK_M_S | 103 |
我发现会话97被一个处于打开事务中休眠的UPDATE会话阻塞,但为什么会话ID 115被103阻塞而非97?115和103均为SELECT会话,且持有相同的锁:
<Database name="[REDACTED]"> <Locks> <Lock request_mode="S" request_status="GRANT" request_count="1" /> </Locks> <Objects> <Object name="blockthis" schema_name="dbo"> <Locks> <Lock resource_type="OBJECT" request_mode="IS" request_status="GRANT" request_count="1" /> <Lock resource_type="PAGE" page_type="*" index_name="PK_IX" request_mode="S" request_status="WAIT" request_count="1" /> </Locks> </Object> </Objects> </Database>
问题解答
这是SQL Server的锁等待链机制导致的。当会话103等待会话97持有的锁时,会进入锁等待队列;后续会话115发起的同资源锁请求,会按顺序排在103之后,因此阻塞关系显示为115被103阻塞,而非直接指向根阻塞者97。
结合锁信息分析:115正在等待PK_IX索引某页的S锁,而该页被会话97的UPDATE事务持有X锁(排他锁)。会话103先于115发起S锁请求并进入等待队列;当115再请求该页S锁时,SQL Server会将其排在103之后等待——即使S锁之间本身兼容,但因为103已经在等待X锁释放,后续请求必须按顺序等待前面的会话完成锁获取或释放,以此保证锁请求的顺序性,降低死锁风险。
简单来说,SQL Server的锁等待是按请求顺序排队的,不会让后续请求绕过前面的等待会话直接关联根阻塞者,所以就出现了115被103阻塞的情况。
内容的提问来源于stack exchange,提问作者cri ron
相关产品推荐
相关产品推荐

