I am trying to simulate a deadlock on SQL Server.
_|worker_id|salary| 1|1 |100 | 2|2 |300 |
Transaction 1 completed in 5 seconds.
/* 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;
Transaction 2 finished in 3 seconds.
/* 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 is not giving any error. Deadlock did not occur. What should I change in order to simulate a deadlock?
In terms of SQL Server, a deadlock occurs when two (or more) processes lock the separate resource. Under these circumstances, each process cannot continue and begins to wait for others to release the resource.
Simulating such a blocking chain requires four separate connections to the SQL Server database to be created. That means that each query must be executed from a separate query tab in the SQL Server Management Studio. The Adventure Works database will be used in the blocking chain example.
Two SELECT statements are not going to deadlock, but a SELECT can deadlock with an UPDATE. When such deadlock occurs, the SELECT is usually the victim as it did not perform any update so is always going to loose the draw.
You can create a deadlock by using the steps shown below. First, create the global temp tables with sample data.
--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
Now open two empty query windows in SSMS. Place the code for session 1 in one query window and the code for session 2 in the other query window. Then execute each of the two sessions step by step, going back and forth between the two query windows as required. Note that each transaction has a lock on a resource that the other transaction is also requesting a lock on.
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> ===========================================================
A deadlock results; one transaction finishes and the other transaction is aborted and error message 1205 is sent to client.
Close the SSMS query windows for "Session 1" and "Session 2" to commit (or rollback) any open transactions. Lastly, cleanup the temp tables:
DROP TABLE ##Employees GO DROP TABLE ##Suppliers GO
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With