我很惊讶地看到一个非常基本的更新声明& select语句可能会变成死锁 我的印象是,如果2个进程在无穷远处等待,那么你只能陷入僵局。我没有得到的是为什么这两个过程不能只是等待彼此。任何帮助将不胜感激。
1个查询来自实体框架,运行非常激烈(大约每2秒一次)。
SELECT
[Extent1].[SubscriptionID] AS [SubscriptionID],
[Extent1].[ClientID] AS [ClientID],
[Extent1].[SubClientID] AS [SubClientID],
[Extent1].[CAClientID] AS [CAClientID],
CASE WHEN ([Extent1].[ArrivalTime] IS NULL) THEN @p__linq__1 ELSE [Extent1].[ArrivalTime] END AS [C1],
[Extent1].[UpdateDate] AS [UpdateDate]
FROM [dbo].[CA_Event_Person] AS [Extent1]
WHERE ([Extent1].[UpdateDate] IS NOT NULL) AND ([Extent1].[UpdateDate] > @p__linq__0)
另一个正在进行更新:
UPDATE
CA_Event_Person
SET
UpdatePersonID = @PersonID,
UpdateDate = GETDATE(),
AutoAssign = ISNULL(@AutoAssign, AutoAssign)
WHERE SubscriptionID = @SubscriptionID
完整死锁图:
<deadlock-list>
<deadlock victim="processc35888508">
<process-list>
<process id="processc35888508" taskpriority="0" logused="0" waitresource="KEY: 9:72057707739217920 (fa9c88953e05)" waittime="3892" ownerId="39577235946" transactionname="SELECT" lasttranstarted="2016-03-02T13:36:42.027" XDES="0x80099800" lockMode="S" schedulerid="15" kpid="9996" status="suspended" spid="109" sbid="0" ecid="5" priority="0" trancount="0" lastbatchstarted="2016-03-02T13:36:42.027" lastbatchcompleted="2016-03-02T13:36:42.027" clientapp="iXtranet.NET2" hostname="HB2949" hostpid="4244" isolationlevel="read committed (2)" xactid="39577235946" currentdb="9" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="adhoc" line="1" stmtstart="102" sqlhandle="0x02000000263a730faf73af4e669327dd034762624d86b5aa">
SELECT
[Extent1].[SubscriptionID] AS [SubscriptionID],
[Extent1].[ClientID] AS [ClientID],
[Extent1].[SubClientID] AS [SubClientID],
[Extent1].[CAClientID] AS [CAClientID],
CASE WHEN ([Extent1].[ArrivalTime] IS NULL) THEN @p__linq__1 ELSE [Extent1].[ArrivalTime] END AS [C1],
[Extent1].[UpdateDate] AS [UpdateDate]
FROM [dbo].[CA_Event_Person] AS [Extent1]
WHERE ([Extent1].[UpdateDate] IS NOT NULL) AND ([Extent1].[UpdateDate] > @p__linq__0) </frame>
<frame procname="unknown" line="1" sqlhandle="0x000000000000000000000000000000000000000000000000">
unknown </frame>
</executionStack>
<inputbuf>
</inputbuf>
</process>
<process id="processf1137fdc8" taskpriority="0" logused="296" waitresource="PAGE: 9:1:11298302" waittime="4074" ownerId="39577243359" transactionname="UPDATE" lasttranstarted="2016-03-02T13:36:42.217" XDES="0x1c47b7280" lockMode="IX" schedulerid="12" kpid="10040" status="suspended" spid="237" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2016-03-02T13:36:42.217" lastbatchcompleted="2016-03-02T13:36:42.213" clientapp="Internet Information Services" hostname="HB2949" hostpid="4244" loginname="WEBCLASSIC2" isolationlevel="read committed (2)" xactid="39577243359" currentdb="9" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="dixyscom.dbo.CA_stp_Subscription_Resource_Append" line="131" stmtstart="7222" sqlhandle="0x03000900ab5fd53ec3e5e3005aa500000100000000000000">
UPDATE
CA_Event_Person
SET
UpdatePersonID = @PersonID,
UpdateDate = GETDATE(),
AutoAssign = ISNULL(@AutoAssign, AutoAssign)
WHERE
SubscriptionID = @SubscriptionID </frame>
</executionStack>
<inputbuf>
Proc [Database Id = 9 Object Id = 1054171051] </inputbuf>
</process>
<process id="process10ad13e748" taskpriority="0" logused="10000" waittime="3892" schedulerid="22" kpid="5452" status="suspended" spid="109" sbid="0" ecid="0" priority="0" trancount="0" lastbatchstarted="2016-03-02T13:36:42.027" lastbatchcompleted="2016-03-02T13:36:42.027" clientapp="iXtranet.NET2" hostname="HB2949" hostpid="4244" loginname="WEBDOTNET3" isolationlevel="read committed (2)" xactid="39577235946" currentdb="9" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
<executionStack>
<frame procname="adhoc" line="1" stmtstart="102" sqlhandle="0x02000000263a730faf73af4e669327dd034762624d86b5aa">
SELECT
[Extent1].[SubscriptionID] AS [SubscriptionID],
[Extent1].[ClientID] AS [ClientID],
[Extent1].[SubClientID] AS [SubClientID],
[Extent1].[CAClientID] AS [CAClientID],
CASE WHEN ([Extent1].[ArrivalTime] IS NULL) THEN @p__linq__1 ELSE [Extent1].[ArrivalTime] END AS [C1],
[Extent1].[UpdateDate] AS [UpdateDate]
FROM [dbo].[CA_Event_Person] AS [Extent1]
WHERE ([Extent1].[UpdateDate] IS NOT NULL) AND ([Extent1].[UpdateDate] > @p__linq__0) </frame>
<frame procname="unknown" line="1" sqlhandle="0x000000000000000000000000000000000000000000000000">
unknown </frame>
</executionStack>
<inputbuf>
(@p__linq__0 datetime2(7),@p__linq__1 datetime2(7))SELECT
[Extent1].[SubscriptionID] AS [SubscriptionID],
[Extent1].[ClientID] AS [ClientID],
[Extent1].[SubClientID] AS [SubClientID],
[Extent1].[CAClientID] AS [CAClientID],
CASE WHEN ([Extent1].[ArrivalTime] IS NULL) THEN @p__linq__1 ELSE [Extent1].[ArrivalTime] END AS [C1],
[Extent1].[UpdateDate] AS [UpdateDate]
FROM [dbo].[CA_Event_Person] AS [Extent1]
WHERE ([Extent1].[UpdateDate] IS NOT NULL) AND ([Extent1].[UpdateDate] > @p__linq__0) </inputbuf>
</process>
</process-list>
<resource-list>
<keylock hobtid="72057707739217920" dbid="9" objectname="dixyscom.dbo.CA_Event_Person" indexname="CIX_CA_Event_Person" id="lock2dda41680" mode="X" associatedObjectId="72057707739217920">
<owner-list>
<owner id="processf1137fdc8" mode="X"/>
</owner-list>
<waiter-list>
<waiter id="processc35888508" mode="S" requestType="wait"/>
</waiter-list>
</keylock>
<pagelock fileid="1" pageid="11298302" dbid="9" objectname="dixyscom.dbo.CA_Event_Person" id="lock44facf180" mode="S" associatedObjectId="72057707632197632">
<owner-list>
<owner id="process10ad13e748" mode="S"/>
</owner-list>
<waiter-list>
<waiter id="processf1137fdc8" mode="IX" requestType="wait"/>
</waiter-list>
</pagelock>
<exchangeEvent id="Pipecd899e380" WaitType="e_waitPipeGetRow" nodeId="1">
<owner-list>
<owner id="processc35888508"/>
</owner-list>
<waiter-list>
<waiter id="process10ad13e748"/>
</waiter-list>
</exchangeEvent>
</resource-list>
</deadlock>
</deadlock-list>
修改的 表上有一些触发器,简而言之就是更新触发器: NUMBER1:
IF EXISTS (SELECT EventID FROM deleted WHERE SubscriptionID = 7379958 and PersonID > 0)
AND EXISTS (SELECT EventID FROM INSERTED WHERE SubscriptionID = 7379958 and PersonID = 0)
BEGIN
RAISERROR('Can''t reset to PersonID 0',16,1)
ROLLBACK
END
2号:
IF EXISTS (SELECT EventID FROM DELETED WHERE EventID > 0) OR EXISTS (SELECT EventID FROM INSERTED WHERE EventID > 0) BEGIN ...
[Enter 30 lines of code that i'm assuming are being skipped due to the no insert or delete)
和数字3(这是更新后的触发器):
ALTER TRIGGER [dbo].[trig_CA_Event_Person_RN_Availability_Recalculate_OnUpdate]
ON [dbo].[CA_Event_Person]
AFTER UPDATE
AS
IF Update(EventID) OR Update(NOPersons) OR Update(StatusID) OR Update(Deleted) OR Update(Cancelled) OR Update(WaitinglistPosition) OR Update(CanBeOverTaken) BEGIN
INSERT INTO
RN_Availability_Recalculate
(
ClientID,
SubClientID,
ApplicationID,
CA_CAClientID,
CA_EventID,
InsertPersonID,
InsertDate,
CompanyID,
Reference
)
SELECT
CA_Event_Head.ClientID,
CA_Event_Head.SubClientID,
CA_Event_Head.ApplicationID,
CA_Event_Head.CAClientID,
CA_Event_Head.EventID,
INSERTED.InsertPersonID,
GETDATE(),
Company.CompanyID,
'trig_CA_Event_Person_RN_OnUpdate'
FROM
INSERTED
INNER JOIN deleted
ON deleted.SubscriptionID = INSERTED.SubscriptionID
AND (
deleted.EventID <> INSERTED.EventID
OR deleted.NOPersons <> INSERTED.NOPersons
OR deleted.ArrivalTime <> INSERTED.ArrivalTime
OR (
deleted.StatusID <> INSERTED.StatusID
AND INSERTED.StatusID IN (50, 98, 99) --vertrokken of geannuleerd
)
)
INNER JOIN CA_Event_Head WITH(NOLOCK)
ON INSERTED.EventID = CA_Event_Head.EventID
INNER JOIN Company WITH(NOLOCK)
ON CA_Event_Head.ClientID = Company.REF_ClientID
AND CA_Event_Head.CAClientID = Company.REF_CA_CAClientID
AND CA_Event_Head.ApplicationID = Company.REF_ApplicationID
WHERE
INSERTED.EventID > 0
AND INSERTED.EventID NOT IN (SELECT CA_EventID FROM RN_Availability_Recalculate WITH (NOLOCK))
AND CA_Event_Head.CAClientID > 0
AND CA_Event_Head.PublicSubscription = 1
AND CA_Event_Head.BlockPublicSubscription = 0
AND CA_Event_Head.EndTime >= GETDATE()
END