我有一個名爲Agent_Events的SQL表,它記錄了「作業」,缺少我們的系統用戶報告的更好的術語。工作將開始,稍後的某個確定時間結束。我們想保留所有系統作業的記錄,所以我們有一個觸發器,當從Agent_Events表中刪除一行時,獲取該記錄並將其插入到report_Agent_Events表中,該作業的記錄隨着作業結束時間而確定到目前爲止。這是觸發器:執行插入導致死鎖的T-SQL觸發器
ALTER TRIGGER [dbo].[tAgentEvents]
ON [dbo].[Agent_Events]
AFTER DELETE
AS
BEGIN
SET NOCOUNT ON
DECLARE @callUID nvarchar(10)
SELECT @callUID = [raw_call_ucid] FROM DELETED
DECLARE @callID bigint
SELECT TOP 1 @callID = [ID] FROM report_ExtensionCalls WHERE UCID = @callUID ORDER BY [time_finished] DESC
INSERT INTO [report_agent_Events]
([Agent_Name],[time_started],[time_ended],[duration],[clientStatus],[agentStatus],[Call_ID],[Reference_ID])
( SELECT
[Agent_Name],[time_started],GETDATE(),DATEDIFF(s,[time_started],GETDATE()),[clientStatus],[agentStatus],@callID as Call_ID,[Reference_ID]
FROM
DELETED
)
END
我們最近發現的是,當系統上有大量活動時,多個作業可能會同時結束。發生這種情況時,觸發將失敗,並以下死鎖錯誤:
Procedure tAgentEvents:
Transaction (Process ID) was deadlocked on lock resources with another process and has been chosen as the deadlock victim RSS
它看起來像在觸發器的INSERT語句與同一INSERT語句在並行觸發規定的鎖衝突。有什麼我可以做,以避免這個問題?這在我看來就像一個非常簡單的觸發器。
在此先感謝。
無論死鎖如何,您的觸發器都需要完全重寫。你的觸發器假定只有一行被刪除。您的查詢需要基於設置,因爲在sql服務器觸發器每個操作調用一次,而不是每行一次。 –
啊好吧,我相信它是這樣寫的,因爲實際上行被存儲過程刪除,這確保只有一行被一次刪除。這仍然會有問題嗎? – Raiden616
是的。出現問題時會發生什麼情況,並且由於系統中的錯誤,有人需要刪除10行。你的觸發器無法正常工作。很容易寫出它們基於集合。在這種情況下,將1列標記爲已刪除的標量確實沒有意義,但其餘標記直接來自已刪除的表。這應該是你的基表,刪除和report_ExtensionCalls –