Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why deadlock occurs?

I use a small transaction which consists of two simple queries: select and update:

SELECT * FROM XYZ WHERE ABC = DEF

and

UPDATE XYZ SET ABC = 123
WHERE ABC = DEF

It is quite often situation when the transaction is started by two threads, and depending on Isolation Level deadlock occurs (RepeatableRead, Serialization). Both transactions try to read and update exactly the same row. I'm wondering why it is happening. What is the order of queries which leads to deadlock? I've read a bit about lock (shared, exclusive) and how long locks last for each isolation level, but I still don't fully understand...

I've even prepared a simple test which always result in deadlock. I've looked at results of the test in SSMS and SQL Server Profiler. I started first query and then immediately the second.

First query:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
SELECT ...
WAITFOR DELAY '00:00:04'
UPDATE ...
COMMIT

Second query:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
SELECT ...
UPDATE ...
COMMIT

Now I'm not able to show you detailed logs, but it looks less or more like this (I've very likely missed Lock:deadlock etc. somewhere):

(1) SQL:BatchStarting: First query
(2) SQL:BatchStarting: Second query
(3) Lock:timeout for second query
(4) Lock:timeout for first query
(5) Deadlock graph

If I understand locks well, in (1) first query takes a shared lock (to execute SELECT), then goes to sleep and keeps the shared lock until the end of transaction. In (2) second query also takes shared lock (SELECT) but cannot take exclusive lock (UPDATE) while there are shared locks on the same row, which results in Lock:timeout. But I can't explain why timeout for second query occurs. Probably I don't understand the whole process well. Can anybody give a good explanation?

I haven't noticed deadlocks using ReadCommitted but I'm afraid they may occur. What solution do you recommend?

like image 604
Grzes Avatar asked Aug 08 '11 19:08

Grzes


People also ask

What are 4 conditions required for deadlock to occur?

The four necessary conditions for a deadlock situation to occur are mutual exclusion, hold and wait, no preemption and circular set. We can prevent a deadlock by preventing any one of these conditions.

Why does SQL deadlock occur?

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.

Why is deadlock a problem?

Deadlocks are a problem in parallel computing systems because of the use of software or hardware synchronization resources or locks to provide mutual exclusion for shared data and process coordination.


2 Answers

A deadlock occurs when two or more tasks permanently block each other by each task having a lock on a resource which the other tasks are trying to lock

http://msdn.microsoft.com/en-us/library/ms177433.aspx

like image 93
David Avatar answered Sep 21 '22 18:09

David


"But I can't explain why timeout for second query occurs."

Because the first query holds shared lock. Then the update in the first query also tries to get the exclusive lock, which makes him sleep. So the first and second query are both sleeping waiting for the other to wake up - and this is a deadlock which results in timeout :-)

In mysql it works better - the deadlock is detected immediatelly and one of the transactions is rolled back (you need not to wait for timeout :-)).

Also, in mysql, you can do the following to prevent deadlock:

select ... for update

which will put a write-lock (i.e. exclusive lock) just from the beginning of the transaction, and this way you avoid the deadlock situation! Perhaps you can do something similar in your database engine.

like image 34
Tomas Avatar answered Sep 21 '22 18:09

Tomas