Write/Read Deadlocks

I love to write about Deadlocks, because there are so many different ways and situations in which you can end up with Deadlocks if you don’t think carefully when writing your code. In today’s blog post I want to show you a very simple Deadlock that can occur when you want to write and read records from the same table in a different order.

A Write/Read Deadlock

The following listing shows a simple table definition statement, where I also insert 2 records.

-- Create a new table
CREATE TABLE Foo
(
	Col1 INT IDENTITY(1, 1) NOT NULL PRIMARY KEY,
	Col2 INT,
	Col3 INT
)
GO

-- Insert 2 records
INSERT INTO Foo VALUES (1, 1), (2, 2)
GO

SELECT * FROM Foo
GO

Imagine now the following situation: you have 2 queries, which access that table for writing and reading, but you access the records in a different order. The first transaction performs the following:

  • UPDATE the 1st record
  • SELECT the 2nd record

And a second transaction accesses both records in the opposite order:

  • UPDATE the 2nd record
  • SELECT the 1st record

The following code shows you both transactions:

-- UPDATE 1st record
-- SELECT 2nd record
BEGIN TRANSACTION

UPDATE Foo SET Col3 = 3
WHERE Col1 = 1

SELECT * FROM Foo
WHERE Col1 = 2

ROLLBACK
GO

-- UPDATE 2nd record
-- SELECT 1st record
BEGIN TRANSACTION

UPDATE Foo SET Col3 = 3
WHERE Col1 = 2

SELECT * FROM Foo
WHERE Col1 = 1

ROLLBACK
GO

If the timing is right (wrong), it’s quite easy to trigger a Deadlock here, because both transactions acquire an Exclusive Lock on the 1st and 2nd record, and then they are not able to acquire the Shared Lock for reading on the other record – Deadlock!

How can you solve that Deadlock? There are many ways:

  • Access the records in the same order (1st record, 2nd record) across all of your transactions
  • Perform the SELECT statement outside of the transaction
  • Enable Read Committed Snapshot Isolation to get rid of the Shared Locks during SELECT statements

Summary

In today’s blog post I wanted to show you how easy it is to trigger a Deadlock in SQL Server when you access records in a table for writing and reading in a different order across transactions. When you write your queries, you always have to think very carefully and implement your queries accordingly. There is always someone else who can block you.

Thanks for your time,

-Klaus

Leave a Reply to Anonymous Cancel Reply

Your email address will not be published. Required fields are marked *