У меня есть таблица SQL Agent_Events, которая регистрирует «задания» из-за отсутствия лучшего термина, о котором сообщают пользователи нашей системы. Запуск начнется и, какое-то неопределенное время спустя, закончится. Мы хотим сохранить запись всех системных заданий, поэтому у нас есть триггер, который, когда строка удаляется из таблицы 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 Server триггеры вызывается один раз за операцию, а не один раз в строке. –
Ах, хорошо, я считаю, что это было написано так, потому что на самом деле строки удаляются хранимой процедурой, которая гарантирует, что только одна строка удаляется сразу. Будет ли это проблематично? – Raiden616
Да. Что происходит, когда есть проблема, и кому-то нужно удалить 10 строк из-за ошибки в системе. Ваш триггер не будет работать правильно. Их легко установить на основе набора. В этом случае не имеет смысла, чтобы 1 столбец был скаляром из удаленных, но остальные из них поступали непосредственно из удаленной таблицы. Это должно быть простым соединением между вашей базовой таблицей, удаленным и report_ExtensionCalls. –