【问题标题】:Understanding the SQL Server deadlock diagram了解 SQL Server 死锁图
【发布时间】:2015-01-01 14:08:58
【问题描述】:

我有一个应用程序将被选为 SQL Server 中的“死锁受害者”。有多个线程尝试执行以下查询。

查询

merge Table_X as target  
using (values ('14410')) as source (CUST_ID) on target.CUST_ID = '14410'
when matched then  
    update 
       SET CUST_NAME = 'xyz', CLOSE_DATE = NULL,
           xx = 2, COMPLETE = 'No', 
           qwert = CASE  WHEN qwert is null and 'Low' = 'High' THEN getDate() ELSE null END, 
           ACTIVE = 1, xcount = '913af80db3f424e34a9055e0ea9bc391'  

when not matched then  
   INSERT (CUST_ID, CUST_NAME, OPEN_DATE, CLOSE_DATE, xx, COMPLETE, qwert, ddd, ACTIVE, xcount )  
   VALUES ('14410', 'U.S. Robotics and Mechanical Men', '2007-08-31 15:14:23.0', NULL, 2, 'No', NULL, 0, 1, '913af80db3f424e34a9055e0ea9bc391') ;

DECLARE @54229 numeric(19,0)
SET @54229 = ( SELECT id from Table_X  where CUST_ID = '14410' )

insert into Table_Y (xyz, abc, ax, ay, az, bx, bxz, bz, UPDATED, abcd) 
   select 
       xyz, abc, ax, ay, az, bx, bxz, bz, UPDATED, abcd 
   from 
       Table_Z 
   where 
       abcd = @54229

merge Table_Z as target 
using (values (@54229)) as source (abcd) on target.abcd = @54229 
when matched then  
    UPDATE  
       SET xyz = 1.1, abc = 1.1, ax = 1.1, ay = 1.1, az = 1.1, 
           bx = 1.1, bxz = 'Low', bz = 1.1, UPDATED = getdate()

when not matched then 
    INSERT (xyz, abc, ax, ay, az, IS_FORCE_EDD, bx, bxz, bz, UPDATED, abcd) 
    VALUES(1.1, 1.1, 1.1, 1.1, 1.1, 0, 1.1,'Low', 1.1, getdate(), @54229);

INSERT INTO Table_A(ACTION, DATE_TIME, PROFILE_ID, USER_ID)
VALUES('Profile Change', getdate(), @54229, 1)  

Deadlock diagram

谁能解释一下这个死锁图?

并为我提供防止这种死锁的解决方案。

我已经阅读了很多东西并尝试了with (nolock)、isolation level,但我没有得到正确的解决方案。

对于死锁受害者,是否存在任何与索引相关的问题?

【问题讨论】:

  • 如果只是缓慢完成,也会出现死锁消息。尝试提高查询的性能。
  • @Hogan 只有在检测到实际死锁时才会引发死锁错误。
  • @MartinSmith - 我不相信有可能检测到死锁 - 我相信使用了启发式方法,并且在一个进程锁定资源和“缓慢”地释放它。
  • @hogan 那么你相信错了。谷歌死锁检测算法。死锁图将包含循环等待的详细信息。

标签: sql-server sql-server-2008


【解决方案1】:

我已经创建了非聚集索引 之后我没有观察到死锁受害者异常。

CREATE NONCLUSTERED INDEX [T_abcd] ON [dbo].[Table_Z]
    (
        [abcd] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    GO

【讨论】:

    【解决方案2】:

    我认为在您的代码中尽早获得对 TABLE_Z 的读取锁定将解决问题。

    这是一个关于此的问题: Obtain Update Table Lock at start of Stored Procedure in SQL Server.

    编辑:您在写入之前从 TABLE_Z 读取。假设您有两个线程/连接(A 和 B)正在运行:

    A 获得读锁

    B 获取读锁

    A 尝试获取写锁,但必须等待 B 释放读锁。

    B 尝试获取写锁,但必须等待 A 释放读锁。

    现在出现了死锁。

    【讨论】:

    • 你能举例说明一下吗?以及表索引有什么作用吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-11
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多