【发布时间】:2014-11-12 04:34:58
【问题描述】:
很奇怪,当有 2 个连接在不同的行上运行以下事务时,会检测到死锁。为什么查询优化器要求事务 T1 有资源 KEY2,即事务 T2 更新的行?
KEY1 (ROW 1) KEY: 5:72057594048348160 (150fa2746afc)
KEY2 (ROW 2) KEY: 5:72057594048348160 (1bec117e39ae)
2 个事务同时更新不同的行。假设它们不会相互干扰 UPLOCK 和 ROWLOCK?
BEGIN TRAN
SELECT * FROM TABLE WITH(UPLOCK, ROWLOCK) WHERE PK_COL1 = ? and PK_COL2 = ?
UPDATE TABLE SET COL3 = ? WHERE PK_COL1 = ? and PK_COL2 = ?
END
以下是死锁列表
<process id="process10e7502c8" taskpriority="0" logused="0" waitresource="KEY: 5:72057594048348160 (150fa2746afc)"
....
<process id="process10e750988" taskpriority="0" logused="0" waitresource="KEY: 5:72057594048348160 (1bec117e39ae)"
...
<resource-list>
<keylock hobtid="72057594048348160" dbid="5" objectname="" indexname="" id="locka6b73300" mode="U" associatedObjectId="72057594048348160">
<owner-list>
<owner id="process10e750988" mode="U" />
</owner-list>
<waiter-list>
<waiter id="process10e7502c8" mode="U" requestType="wait" />
</waiter-list>
</keylock>
<keylock hobtid="72057594048348160" dbid="5" objectname="" indexname="" id="locka5319b80" mode="U" associatedObjectId="72057594048348160">
<owner-list>
<owner id="process10e7502c8" mode="U" />
</owner-list>
<waiter-list>
<waiter id="process10e750988" mode="U" requestType="wait" />
</waiter-list>
</keylock>
</resource-list>
这是发生死锁时的 sp_lock 结果
spid dbid ObjId IndId Type Resource Mode Status
51 5 0 0 DB S GRANT
52 6 0 0 DB S GRANT
53 4 0 0 DB S GRANT
54 5 0 0 DB S GRANT
54 5 1941581955 0 TAB IX GRANT
54 5 1941581955 1 KEY (1bec117e39ae) U GRANT
54 5 0 0 MD 4(6:0:0) Sch-S GRANT
54 5 1941581955 1 KEY (150fa2746afc) U WAIT
54 5 1941581955 1 PAG 1:73626 IU GRANT
57 5 0 0 DB S GRANT
58 6 0 0 DB S GRANT
58 6 0 0 APP 16384:[Repl-LogRead]:(04dddec9) X GRANT
59 5 0 0 DB S GRANT
60 6 0 0 DB S GRANT
61 5 0 0 DB S GRANT
62 5 0 0 DB S GRANT
63 4 0 0 DB S GRANT
64 4 0 0 DB S GRANT
65 5 0 0 DB S GRANT
65 5 1941581955 1 KEY (1bec117e39ae) U WAIT
65 5 1941581955 1 PAG 1:73626 IU GRANT
65 5 0 0 MD 4(6:0:0) Sch-S GRANT
65 5 1941581955 1 KEY (150fa2746afc) U GRANT
65 5 1941581955 0 TAB IX GRANT
66 6 0 0 APP 16384:[DC1ISGSD03\I]:(152e28ac) X GRANT
66 6 0 0 DB S GRANT
67 1 1131151075 0 TAB IS GRANT
69 5 0 0 DB S GRANT
如果我添加一个与主键创建的聚集索引具有相同列和排序的非聚集索引,死锁问题就会消失。但是为什么更新聚集索引键上的一行需要其他聚集索引键上的更新锁呢?
如果我有任何误解,请纠正我。任何答案将不胜感激。
表模式描述如下 SQL 脚本
create table [dbo].[TABLE1]
(
[PK_COL1] char(10) not null,
[PK_COL2] char(10) not null,
[COL3] char(10) not null,
PRIMARY KEY ([PK_COL1],[PK_COL2])
);
【问题讨论】:
-
米奇,答案不行。
-
聚集索引碎片严重吗?
-
不应该。它只有不到 100 条记录。我尝试重建索引,但死锁问题仍然发生。
-
请发布您的完整 TSQL 表架构定义。
标签: sql-server