I have two transaction: T1 with SERIALIZABLE
isolation level and T2 (I think - with default READ COMMITTED
isolation level, but it doesn't matter).
Transaction T1 performs SELECT
then WAITFOR
2 seconds then SELECT
.
Transaction T2 performs UPDATE
on data which T1 read.
It causes deadlock, why transaction T2 don't wait for end of T1?
When T1 has REPEATABLE READ
isolation level everything is OK i.e. phantom rows occur.
I thought when I raise isolation level up to SERIALIZABLE
, T2 will wait for end of T1.
This is a part of my college exercise. I have to show negative effects in two parallel transactions which have incorrect isolation level and absence of these effects with correct isolation level.
Here's the code, unfortunately names of fields are in Polish.
T1:
USE MR; SET IMPLICIT_TRANSACTIONS OFF; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; BEGIN TRANSACTION; -- 1. zapytanie SELECT www.IdSamochodu, s.Model, s.Marka, s.NrRejestracyjny, o.PESEL, o.Nazwisko, o.Imie, o.NrTelefonu FROM WizytyWWarsztacie www JOIN Samochody s ON s.IdSamochodu = www.IdSamochodu JOIN Osoby o ON o.PESEL = s.PESEL WHERE www.[Status] = 'gotowy_do_odbioru' ORDER BY www.IdSamochodu ASC ; WAITFOR DELAY '00:00:02'; -- 2. zapytanie SELECT u.IdSamochodu, tu.Nazwa, tu.Opis, u.Oplata FROM Uslugi u JOIN TypyUslug tu ON tu.IdTypuUslugi = u.IdTypuUslugi JOIN WizytyWWarsztacie www ON www.IdSamochodu = u.IdSamochodu AND www.DataOd = u.DataOd WHERE www.[Status] = 'gotowy_do_odbioru' ORDER BY u.IdSamochodu ASC, u.Oplata DESC ; COMMIT;
T2:
USE MR; SET IMPLICIT_TRANSACTIONS OFF; SET TRANSACTION ISOLATION LEVEL READ COMMITTED; BEGIN TRANSACTION; UPDATE Uslugi SET [Status] = 'wykonano' WHERE IdUslugi = 2 ; UPDATE www SET www.[Status] = 'gotowy_do_odbioru' FROM WizytyWWarsztacie www WHERE www.[Status] = 'wykonywanie_usług' AND EXISTS ( SELECT 1 FROM Uslugi u WHERE u.IdSamochodu = www.IdSamochodu AND u.DataOd = www.DataOd AND u.[Status] = 'wykonano' GROUP BY u.IdSamochodu, u.DataOd HAVING COUNT(u.IdUslugi) = ( SELECT COUNT(u2.IdUslugi) FROM Uslugi u2 WHERE u2.IdSamochodu = www.IdSamochodu AND u2.DataOd = www.DataOd GROUP BY u2.IdSamochodu, u2.DataOd ) ) ; COMMIT;
I use SQL Management Studio and I have each transaction in different file. I run this by clicking F5 in T1 then quickly switch to file which contains T2 and again - F5.
I read about deadlocks and locking mechanism in mssql but apparently, I haven't understand this topic yet.
Deadlock issue in SQL Server 2008 R2 (.Net 2.0 Application)
SQL Server deadlocks between select/update or multiple selects
http://msdn.microsoft.com/en-us/library/ms173763(v=sql.105).aspx
http://www.sql-server-performance.com/2004/advanced-sql-locking/
edit
I figure out the first UPDATE statement in T2 causes the problem, why?