You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否在SQL Server中无需修改表,实现两个进程的死锁模拟?

在SQL Server中无需修改表模拟死锁的可行方案

完全可行,不需要修改表数据,通过事务内的共享锁持有+循环锁等待就能模拟死锁,以下是具体操作步骤(以存在数据的Person.Person表为例,换成你自己的业务表也可以):

步骤1:打开两个独立的SQL Server查询会话

比如在SSMS里打开两个新的查询窗口,分别作为会话A和会话B。

会话A操作:

开启事务,查询并锁定第一部分数据(锁会保持到事务结束):

BEGIN TRANSACTION;
-- 用HOLDLOCK让共享锁持有至事务结束,ROWLOCK指定行级锁
SELECT * FROM Person.Person WHERE BusinessEntityID BETWEEN 1 AND 100 WITH (HOLDLOCK, ROWLOCK);

会话B操作:

同样开启事务,查询并锁定另一部分数据:

BEGIN TRANSACTION;
SELECT * FROM Person.Person WHERE BusinessEntityID BETWEEN 101 AND 200 WITH (HOLDLOCK, ROWLOCK);

触发死锁:

  1. 回到会话A,执行查询请求会话B持有的锁:
SELECT * FROM Person.Person WHERE BusinessEntityID BETWEEN 101 AND 200 WITH (HOLDLOCK, ROWLOCK);
  1. 立刻切换到会话B,执行查询请求会话A持有的锁:
SELECT * FROM Person.Person WHERE BusinessEntityID BETWEEN 1 AND 100 WITH (HOLDLOCK, ROWLOCK);

此时SQL Server的死锁检测机制会立刻触发,其中一个会话会收到死锁错误提示(通常是Msg 1205, Level 13, State 51),事务自动回滚,另一个会话可以继续执行。

原理说明:

  • HOLDLOCK(等价于SERIALIZABLE隔离级别的锁行为)会让查询获取的共享锁一直持有到事务提交/回滚,而不是默认的查询结束就释放。
  • 两个会话先分别持有不同范围的行锁,之后互相请求对方持有的锁,形成循环等待链,满足死锁的四个必要条件(互斥、请求与保持、不可剥夺、循环等待),从而触发死锁。

内容的提问来源于stack exchange,提问作者Jaybee72

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 19:18:20