我遇到两个select语句之间死锁的典型情况。 我有一个JMS监听器正在运行,同时处理两条jms消息。
他们都运行一个选择查询,我最终在同一个表上都有一个键锁。这是死锁的细节。
<deadlock-list>
<deadlock victim="process276e56fcca8">
<process-list>
<process id="process276e56fcca8" taskpriority="0" logused="764" waitresource="KEY: 7:72057594422558720 (8e392f9a7525)" waittime="4129" ownerId="24935297" transactionname="implicit_transaction" lasttranstarted="2017-09-02T10:01:18.853" XDES="0x276dd31f7b8" lockMode="S" schedulerid="5" kpid="25308" status="suspended" spid="65" sbid="0" ecid="0" priority="0" trancount="1" lastbatchstarted="2017-09-02T10:01:18.963" lastbatchcompleted="2017-09-02T10:01:18.963" lastattention="1900-01-01T00:00:00.963" clientapp="Microsoft JDBC Driver for SQL Server" hostname="GAETAN-PC" hostpid="0" loginname="fundhive" isolationlevel="read committed (2)" xactid="24935297" currentdb="7" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128058">
<executionStack>
<frame procname="adhoc" line="1" stmtend="274" sqlhandle="0x02000000ad097723a3df0ffd0ae8c2aae2d6e9938b5224fa0000000000000000000000000000000000000000">
unknown </frame>
<frame procname="unknown" line="1" sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">
unknown </frame>
</executionStack>
<inputbuf>
select * ,61 as userId from getDocumentWorkflowMessages(20285) where 1=1 and vehicleGroupId = '10372' and investorLevelGroupId = '13933' </inputbuf>
</process>
<process id="process276f302fc28" taskpriority="0" logused="764" waitresource="KEY: 7:72057594422558720 (7d9127e683cc)" waittime="4188" ownerId="24935134" transactionname="implicit_transaction" lasttranstarted="2017-09-02T10:01:18.690" XDES="0x27671594728" lockMode="S" schedulerid="3" kpid="13788" status="suspended" spid="73" sbid="0" ecid="0" priority="0" trancount="1" lastbatchstarted="2017-09-02T10:01:18.783" lastbatchcompleted="2017-09-02T10:01:18.783" lastattention="1900-01-01T00:00:00.783" clientapp="Microsoft JDBC Driver for SQL Server" hostname="GAETAN-PC" hostpid="0" loginname="fundhive" isolationlevel="read committed (2)" xactid="24935134" currentdb="7" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128058">
<executionStack>
<frame procname="adhoc" line="1" stmtend="274" sqlhandle="0x0200000046471c35dd8038f6b5d5a8a05c3680d8fe3b66dc0000000000000000000000000000000000000000">
unknown </frame>
<frame procname="unknown" line="1" sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">
unknown </frame>
</executionStack>
<inputbuf>
select * ,61 as userId from getDocumentWorkflowMessages(20285) where 1=1 and vehicleGroupId = '10385' and investorLevelGroupId = '14481' </inputbuf>
</process>
</process-list>
<resource-list>
<keylock hobtid="72057594422558720" dbid="7" objectname=" DocumentWorkflowStatuses" indexname="idx_DocumentWorkflowStatuses_isArchived" id="lock276c4fac900" mode="X" associatedObjectId="72057594422558720">
<owner-list>
<owner id="process276f302fc28" mode="X"/>
</owner-list>
<waiter-list>
<waiter id="process276e56fcca8" mode="S" requestType="wait"/>
</waiter-list>
</keylock>
<keylock hobtid="72057594422558720" dbid="7" objectname=" DocumentWorkflowStatuses" indexname="idx_DocumentWorkflowStatuses_isArchived" id="lock276e1728600" mode="X" associatedObjectId="72057594422558720">
<owner-list>
<owner id="process276e56fcca8" mode="X"/>
</owner-list>
<waiter-list>
<waiter id="process276f302fc28" mode="S" requestType="wait"/>
</waiter-list>
</keylock>
</resource-list>
</deadlock>
</deadlock-list>
我阅读了很多帖子,但我不确定如何处理这个问题。我在表DocumentWorkflowStatus上尝试使用和不使用索引,但它是相同的。
这是getDocumentWorkflowMessages查询:
CREATE FUNCTION [dbo].[getDocumentWorkflowMessages]
(
@projectId bigint
)
RETURNS TABLE
RETURN
SELECT t.*
,dbo.WorkflowStatuses.id AS workflowStatusId
,(
CASE
WHEN isnull(t.workflowScheme_fk, - 1) = - 1 -- IS NULL
THEN ''
ELSE dbo.WorkflowStatuses.NAME
END
) AS workflowStateName
,dbo.WorkflowStatuses.id AS workflowStateId
,CASE
WHEN isnull(t.workflowScheme_fk, '') = ''
THEN - 1
WHEN WorkflowStatusCategories.id IS NOT NULL
THEN WorkflowStatusCategories.id
ELSE isnull((
SELECT TOP 1 id
FROM dbo.getWorstWorkflowIdForStructure(t.projectLanguageId, t.vehicleGroupId, t.investorLevelGroupId, t.structureId)
), - 1)
END AS worstWorkflowCategoryId
from
dbo.getProjectDetailView(@projectId,1) t
LEFT JOIN
dbo.DocumentWorkflowStatuses docs ON docs.structure_fk = t.structureId
AND isnull(docs.versionLanguage_fk, - 1) = isnull(t.projectLanguageId, - 1)
AND isnull(docs.vehicleGroup_fk, 0) = isnull(t.vehicleGroupId, 0)
AND isnull(docs.vehicleInvestorGroup_fk, 0) = isnull(t.investorLevelGroupId, 0)
AND isnull(docs.country_fk, 0) = isnull(t.countryId,0)
LEFT JOIN
dbo.WorkflowStatuses
ON WorkflowStatuses.id = docs.workflowStatus_fk
LEFT JOIN
dbo.WorkflowStatusCategories
ON WorkflowStatusCategories.id = WorkflowStatuses.workflowStatusCategory_fk
GO
这是我的索引:
CREATE NONCLUSTERED INDEX idx_DocumentWorkflowStatuses_isArchived
ON [dbo].[DocumentWorkflowStatuses] ([structure_fk],[versionLanguage_fk],[vehicleGroup_fk],[vehicleInvestorGroup_fk],[country_fk])
INCLUDE ( [workflowStatus_fk])
GO