为何SqlCommand执行SQL Server批量删除时会引发锁导致查询阻塞?
原因分析
批处理执行的上下文持续性差异
在SSMS中运行循环删除脚本时,每次事务提交后,SQL Server会立即释放本次删除操作持有的锁,且SSMS的查询执行器在循环间隙会给数据库留出锁释放的时间窗口。但当通过SqlCommand将整个脚本作为单一批处理异步执行时,脚本会在一个连续的执行上下文中运行,SQL Server可能会优化执行计划(比如复用扫描范围),导致锁的持有时间被延长,甚至在循环间隙也不会完全释放,从而阻塞后续的进度查询。事务隔离级别与读取行为的隐性差异
SSMS默认使用READ COMMITTED隔离级别,若数据库开启了READ_COMMITTED_SNAPSHOT选项,SSMS的查询会自动使用快照读取,无需等待锁释放。而SqlCommand在异步执行时,若未显式配置隔离级别或启用快照读取,可能会使用传统的READ COMMITTED隔离模式,此时读取操作需要等待删除操作的锁释放,从而出现阻塞。连接持有的锁粒度差异
在SSMS中,每次循环的删除事务提交后,连接会短暂处于空闲状态,SQL Server会及时回收锁资源。但SqlCommand异步执行整个脚本时,连接在脚本全程保持占用状态,SQL Server可能会为连续的删除操作分配更高粒度的锁(如页锁、表级意向锁),而非行锁,这类锁的释放延迟会直接阻塞进度查询的读取操作。
内容的提问来源于stack exchange,提问作者Dan Friedman
相关产品推荐
相关产品推荐

