sql server 2008两个并行事务中的死锁

rzy*_*mek 5 sql database sql-server deadlock

我有两个事务:T1与SERIALIZABLE隔离级别和T2(我认为 - 默认READ COMMITTED隔离级别,但没关系).

SELECT然后事务T1执行WAITFOR2秒SELECT.

事务T2 UPDATE对T1读取的数据执行.

它导致死锁,为什么事务T2不等待T1的结束?

当T1具有REPEATABLE READ隔离级别时,一切正常,即出现幻像行.我想当我提高隔离级别时SERIALIZABLE,T2将等待T1的结束.

这是我大学练习的一部分.我必须在两个并行事务中显示负面影响,这些事务具有不正确的隔离级别,并且缺少具有正确隔离级别的这些影响

这是代码,不幸的是字段的名称是波兰语.

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;

我使用SQL Management Studio,每个事务都在不同的文件中.我通过在T1中单击F5然后快速切换到包含T2的文件并再次--F5来运行此操作.

我在mssql中读到了关于死锁和锁定机制,但显然我还没有理解这个主题.

SQL Server 2008 R2中的死锁问题(.Net 2.0应用程序)

SQL Server在select/update或多个选择之间发生死锁

SELECT/UPDATE上的死锁

http://msdn.microsoft.com/en-us/library/ms173763(v=sql.105).aspx

http://www.sql-server-performance.com/2004/advanced-sql-locking/

编辑

我弄清楚T2中的第一个UPDATE语句导致问题,为什么?

Ben*_*hul 6

解决死锁问题从获取死锁图开始.这是一个xml文档,它告诉您有关所涉及的事务和资源的相关位.您可以通过Profiler,扩展事件或事件通知获取它(我确信还有其他方法,但现在这样做).获得图表后,检查它以查看每个事务对哪些资源具有什么类型的锁定.你去哪里真的取决于图中发生了什么,所以我会停在那里.底线:获取死锁图并挖掘它以获取详细信息.

顺便说一句,说一个或另一个交易"导致"僵局有点误导.所有涉及死锁的事务都是导致死锁情况所必需的,因此两者都不是更多的错误.


rzy*_*mek 1

我的 SQL Managmenet Studio 遇到了一些问题(Profiler 不起作用),但最终我获得了死锁图这篇文章对我很有帮助。

僵局

为了理解这个图,我必须了解锁定机制和符号。
我想这里已经解释得很清楚了。

现在,当我了解所有这些内容时,僵局的原因就很明显了。
我为所描述的情况制作了序列图:

顺序图

正如我之前所写,当我们从事务 T2 中删除第一个 UPDATE 语句时,不会发生死锁。

在这种情况下,T2 不会获取pk_uslugi索引上的锁,因此事务 T1 中的第二个 SELECT 语句将成功执行,并且索引pk_wizytywwarsztacie将被解锁。之后,T2也将完成。