【发布时间】:2017-11-15 05:31:07
【问题描述】:
目标数据库: MS SQL Server 2012
要求:在表格中维护用户工作量的摘要。以下是用于维护此摘要的表结构。表正在更新分配给用户的工作项状态的修改。
- PARTICIPANT_ID varchar NO PK,唯一非聚集索引
- OFFERED_COUNT 个数字 YES
- ALLOCATED_COUNT 个数字是
- STARTED_COUNT 个数字 YES
- SUSPENDED_COUNT 个数字是
问题:我们在这张桌子上经常遇到死锁。特此附上死锁图供参考。
目前已完成调查:
- 死锁中的目标行(更新)是相互独立的,因此没有一个事务等待另一个事务放弃锁定的问题。即使插入到表中也会成为死锁的一部分。
- 同一事务在 Oracle 中处理类似的并发负载。
- 怀疑该表被锁定而不是特定行,我们甚至尝试使用以下命令禁用表的锁升级,但死锁仍然存在。
ALTER TABLE Table_name SET(LOCK_ESCALATION DISABLE)
死锁图
<deadlock>
<victim-list>
<victimProcess id="process133f03d498" />
</victim-list>
<process-list>
<process id="process133f03d498" taskpriority="0" logused="3308" waitresource="RID: 11:1:819250:71" waittime="2377" ownerId="29578701" transactionname="implicit_transaction" lasttranstarted="2017-11-09T09:29:43.397" XDES="0x10b0b716a8" lockMode="U" schedulerid="6" kpid="7332" status="suspended" spid="210" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2017-11-09T09:29:45.977" lastbatchcompleted="2017-11-09T09:29:45.397" lastattention="1900-01-01T00:00:00.397" clientapp="jTDS" hostname="PAWSPPAS02" hostpid="123" loginname="STG_SUITE_SSO" isolationlevel="read committed (2)" xactid="29578701" currentdb="11" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128058">
<executionStack>
<frame procname="adhoc" line="1" stmtstart="40" sqlhandle="0x02000000ee409c1fd278abb7f476707399656cbedec9d1960000000000000000000000000000000000000000">
update [RS_WI_PARTICIPANT_SUMM] set [ALLOCATED_COUNT]=[ALLOCATED_COUNT]-1 where [PARTICIPANT_ID]= @P0 </frame>
</executionStack>
<inputbuf>
(@P0 nvarchar(4000))update [RS_WI_PARTICIPANT_SUMM] set [ALLOCATED_COUNT]=[ALLOCATED_COUNT]-1 where [PARTICIPANT_ID]= @P0 </inputbuf>
</process>
<process id="processc70140188" taskpriority="0" logused="85392" waitresource="RID: 11:1:819250:30" waittime="2196" ownerId="29574187" transactionname="implicit_transaction" lasttranstarted="2017-11-09T09:29:16.427" XDES="0x1150f5d6a8" lockMode="U" schedulerid="4" kpid="384" status="suspended" spid="141" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2017-11-09T09:29:46.157" lastbatchcompleted="2017-11-09T09:29:45.470" lastattention="1900-01-01T00:00:00.470" clientapp="jTDS" hostname="PAWSPPAS02" hostpid="123" loginname="STG_SUITE_SSO" isolationlevel="read committed (2)" xactid="29574187" currentdb="11" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128058">
<executionStack>
<frame procname="adhoc" line="1" stmtstart="40" sqlhandle="0x020000001c3c261d27cfa98e13a9cb06f6c30e40cfcaa4a50000000000000000000000000000000000000000">
update [RS_WI_PARTICIPANT_SUMM] set [ALLOCATED_COUNT]=[ALLOCATED_COUNT]+1 where [PARTICIPANT_ID]= @P0 </frame>
</executionStack>
<inputbuf>
(@P0 nvarchar(4000))update [RS_WI_PARTICIPANT_SUMM] set [ALLOCATED_COUNT]=[ALLOCATED_COUNT]+1 where [PARTICIPANT_ID]= @P0 </inputbuf>
</process>
</process-list>
<resource-list>
<ridlock fileid="1" pageid="819250" dbid="11" objectname="STG_SUITE_SSO.dbo.RS_WI_PARTICIPANT_SUMM" id="lock1236714900" mode="X" associatedObjectId="72057599198953472">
<owner-list>
<owner id="processc70140188" mode="X" />
</owner-list>
<waiter-list>
<waiter id="process133f03d498" mode="U" requestType="wait" />
</waiter-list>
</ridlock>
<ridlock fileid="1" pageid="819250" dbid="11" objectname="STG_SUITE_SSO.dbo.RS_WI_PARTICIPANT_SUMM" id="lockdacb14f00" mode="X" associatedObjectId="72057599198953472">
<owner-list>
<owner id="process133f03d498" mode="X" />
</owner-list>
<waiter-list>
<waiter id="processc70140188" mode="U" requestType="wait" />
</waiter-list>
</ridlock>
</resource-list>
</deadlock>
【问题讨论】:
-
这张表有索引吗?有多少索引包含
[PARTICIPANT_ID]作为第一列?我的理由是:在您的情况下,死锁是由于不同进程使用不同的索引而发生的。如果您添加索引提示以强制所有进程使用相同的索引,您的问题可能就会消失。 SQL Server对索引和表分别加锁,因此如果不同的进程使用不同的索引,可能会出现问题。 -
Alex,我们在 [PARTICIPANT_ID] 列上只有一个非聚集索引。感谢您的及时回复。
-
桌子有多大?如果它足够小,那么简单的表扫描也是可能的。
标签: sql-server deadlock database-deadlocks