了解 SQL 服务器死锁图
Understanding the SQL Server deadlock diagram
我有一个应用程序将被选为 SQL 服务器中的 "deadlock victim"。有多个线程尝试执行以下查询。
查询
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)
谁能解释一下这个死锁图?
并为我提供防止此死锁的解决方案。
我已经阅读了很多东西并尝试了 with (nolock)
、isolation level
,但我没有找到合适的解决方案。
死锁受害者是否可能遇到与索引相关的问题?
我认为在您的代码中尽早对 TABLE_Z 进行读取锁定将解决问题。
这里有一个问题:
Obtain Update Table Lock at start of Stored Procedure in SQL Server.
编辑:您正在阅读 TABLE_Z,然后再写入。假设您有两个 threads/connections (A & B) 运行:
A 取得读锁
B 获取读锁
A 尝试获取写锁,但必须等待 B 释放读锁。
B 尝试获取写锁,但必须等待 A 释放读锁。
现在出现了僵局。
我创建了非聚集索引
在那之后我没有观察到死锁受害者异常。
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
我有一个应用程序将被选为 SQL 服务器中的 "deadlock victim"。有多个线程尝试执行以下查询。
查询
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)
谁能解释一下这个死锁图?
并为我提供防止此死锁的解决方案。
我已经阅读了很多东西并尝试了 with (nolock)
、isolation level
,但我没有找到合适的解决方案。
死锁受害者是否可能遇到与索引相关的问题?
我认为在您的代码中尽早对 TABLE_Z 进行读取锁定将解决问题。
这里有一个问题: Obtain Update Table Lock at start of Stored Procedure in SQL Server.
编辑:您正在阅读 TABLE_Z,然后再写入。假设您有两个 threads/connections (A & B) 运行:
A 取得读锁
B 获取读锁
A 尝试获取写锁,但必须等待 B 释放读锁。
B 尝试获取写锁,但必须等待 A 释放读锁。
现在出现了僵局。
我创建了非聚集索引 在那之后我没有观察到死锁受害者异常。
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