模拟超过 2 个进程的死锁

SQL*_*DBA 6 sql-server deadlock

如何在 SQL Server 测试环境中模拟超过 2 个进程的死锁?有人可以帮我写代码吗?再次澄清我的问题,我不希望只有 2 个进程的死锁模拟。我知道如何用 2 个进程产生死锁,但不能用两个以上的进程产生死锁。

Rem*_*anu 19

如果你知道如何用 2 模拟它,你就知道如何用 3 或 N 模拟它。 你必须建立一个循环图:

  • 2个节点:A->B->A(进程A等待B,进程B等待A)
  • 3个节点:A->B->C->A(进程A等待B,B等待C,C等待A)
  • ...
  • N 个节点:P 1 ->P 2 ->...P n ->P 1

要构造 P x ->P y原语(进程 X 等待进程 Y),请使用您最喜欢的阻塞机制。例如,特定键 P 1 ->P 2 ->P 3 ->P 1上的行锁定:

CREATE TABLE rows (key INT NOT NULL PRIMARY KEY);
Run Code Online (Sandbox Code Playgroud)

1) P 1,来自会话 1:

BEGIN TRANSACTION
INSERT INTO rows (key) VALUES (1);
Run Code Online (Sandbox Code Playgroud)

2) P 2,来自会话 2:

BEGIN TRANSACTION
INSERT INTO rows (key) VALUES (2);
Run Code Online (Sandbox Code Playgroud)

3) 让 P 1等待 P 2。从会话 1:

SELECT key FROM rows WHERE key = 2;
Run Code Online (Sandbox Code Playgroud)

4) 继续 P 3,会话 3:

BEGIN TRANSACTION
INSERT INTO rows (key) VALUES (3);
Run Code Online (Sandbox Code Playgroud)

5)在会话 2 中添加 P 2 -> P 3等待:

SELECT key FROM rows WHERE key = 3;
Run Code Online (Sandbox Code Playgroud)

6) 要完成循环,在会话 3 中添加 P 3 -> P 1等待:

SELECT key FROM rows WHERE key = 1;
Run Code Online (Sandbox Code Playgroud)

由于等待图创建了一个循环,这 3 个进程现在处于死锁状态。很快,引擎死锁检测机制(它会定期遍历等待图寻找循环)检测到这个循环并通过选择一个受害者并中止它的事务来打破它,然后在受害者会话中引发错误 1205。

要扩展到 N 个节点,请根据需要重复步骤 4) 和 5)。