SQL Serverでデッドロックをシミュレートしようとしています。
_|worker_id|salary|
1|1 |100 |
2|2 |300 |
トランザクション1は5秒で完了しました。
/* TRANSACTION 1*/
Use dbmcw;
DECLARE @sal1 INT, @sal2 int;
BEGIN TRAN;
SELECT @sal1 = salary
FROM dbo.deadlock_demonstration WITH(UPDLOCK)
WHERE worker_id = 1;
WAITFOR DELAY '00:00:05.000';
SELECT @sal2 = salary
FROM dbo.deadlock_demonstration WITH(UPDLOCK)
WHERE worker_id = 2;
COMMIT TRAN;
トランザクション2は3秒で終了しました。
/* TRANSACTION 2*/
Use dbmcw;
DECLARE @sal1 INT, @sal2 int;
BEGIN TRAN;
SELECT @sal2 = salary
FROM dbo.deadlock_demonstration WITH(UPDLOCK)
WHERE worker_id = 2;
SELECT @sal1 = salary
FROM dbo.deadlock_demonstration WITH(UPDLOCK)
WHERE worker_id = 1;
COMMIT TRAN;
SQL Serverはエラーを出していません。デッドロックは発生しませんでした。デッドロックをシミュレートするには、何を変更する必要がありますか?
以下に示す手順を使用して、デッドロックを作成できます。まず、サンプルデータを使用してグローバル一時テーブルを作成します。
--Two global temp tables with sample data for demo purposes.
CREATE TABLE ##Employees (
EmpId INT IDENTITY,
EmpName VARCHAR(16),
Phone VARCHAR(16)
)
GO
INSERT INTO ##Employees (EmpName, Phone)
VALUES ('Martha', '800-555-1212'), ('Jimmy', '619-555-8080')
GO
CREATE TABLE ##Suppliers(
SupplierId INT IDENTITY,
SupplierName VARCHAR(64),
Fax VARCHAR(16)
)
GO
INSERT INTO ##Suppliers (SupplierName, Fax)
VALUES ('Acme', '877-555-6060'), ('Rockwell', '800-257-1234')
GO
次に、SSMSで2つの空のクエリウィンドウを開きます。 1つのクエリウィンドウにセッション1のコードを配置し、もう1つのクエリウィンドウにセッション2のコードを配置します。次に、2つのセッションのそれぞれをステップごとに実行し、必要に応じて2つのクエリウィンドウ間を行き来します。各トランザクションは、他のトランザクションもロックを要求しているリソースをロックしていることに注意してください。
Session 1 | Session 2
===========================================================
BEGIN TRAN; | BEGIN TRAN;
===========================================================
UPDATE ##Employees
SET EmpName = 'Mary'
WHERE EmpId = 1
===========================================================
| UPDATE ##Suppliers
| SET Fax = N'555-1212'
| WHERE SupplierId = 1
===========================================================
UPDATE ##Suppliers
SET Fax = N'555-1212'
WHERE SupplierId = 1
===========================================================
<blocked> | UPDATE ##Employees
| SET Phone = N'555-9999'
| WHERE EmpId = 1
===========================================================
| <blocked>
===========================================================
デッドロックが発生します。 1つのトランザクションが終了し、他のトランザクションは中止され、エラーメッセージ1205がクライアントに送信されます。
「セッション1」と「セッション2」のSSMSクエリウィンドウを閉じて、開いているトランザクションをコミット(またはロールバック)します。最後に、一時テーブルをクリーンアップします。
DROP TABLE ##Employees
GO
DROP TABLE ##Suppliers
GO