T-SQL触发器导致阻塞

时间:2012-08-06 21:21:15

标签: sql-server sql-server-2008 tsql locking blocking

帮助!以下触发器会在执行后导致阻塞:

USE [Automation]
GO
/****** Object:  Trigger [dbo].[AfterInsertSendEmail]    Script Date: 08/06/2012 22:05:54 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      Chris Cannon
-- Create date: 20120806
-- Description: TBC
-- =============================================
ALTER TRIGGER [dbo].[AfterInsertSendEmail] 
   ON  [dbo].[Enquiry] 
   AFTER INSERT
AS 
BEGIN;
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for trigger here
    DECLARE @l_profile_name nvarchar(128) = 'Automation Enquiries';
    DECLARE @l_importance varchar(6) = 'High';
    DECLARE @l_sensitivity varchar(12) = 'Personal';
    DECLARE @l_recipients varchar(500) = 'a.n.other@somewhere.co.uk';
    DECLARE @l_copy_recipients varchar(500) = 'b.n.other@somewhere.co.uk';
    DECLARE @l_blind_copy_recipients varchar(500) = 'c.n.other@somewhere.co.uk';
    DECLARE @l_reply_to varchar(500) = (SELECT [EmailAddress] FROM [inserted]);
    DECLARE @l_subject nvarchar(255) = (SELECT 'New Enquiry From ' + [FirstName] + ' ' + [LastName] FROM [inserted]);
    DECLARE @l_body nvarchar(500) = 'TBC';
    DECLARE @l_query nvarchar(500) = 'SELECT TOP(1) * FROM [Automation].[dbo].[Enquiry] ORDER BY [Id] DESC';
    DECLARE @l_query_result_separator char(1) = CHAR(9);
    DECLARE @l_query_result_no_padding bit = 1;
    DECLARE @l_attach_query_result_as_file bit = 1;
    DECLARE @l_query_attachment_filename nvarchar(260) = (SELECT 'automation_enquiry_' + REPLACE(REPLACE(REPLACE(CONVERT(nvarchar(19), [DateSubmitted], 120), '-', ''), ' ', ''), ':', '') + '.csv' FROM [inserted]);
    DECLARE @l_append_query_error bit = 1;

    EXEC [msdb].[dbo].[sp_send_dbmail]
          @profile_name = @l_profile_name
        , @importance = @l_importance
        , @sensitivity = @l_sensitivity
        , @recipients = @l_recipients
        , @copy_recipients = @l_copy_recipients
        , @blind_copy_recipients = @l_blind_copy_recipients
        , @reply_to = @l_reply_to
        , @subject = @l_subject
        , @body = @l_body
        , @query = @l_query
        , @query_result_separator = @l_query_result_separator
        , @query_result_no_padding = @l_query_result_no_padding
        , @attach_query_result_as_file = @l_attach_query_result_as_file
        , @query_attachment_filename = @l_query_attachment_filename
        , @append_query_error = @l_append_query_error;

END;

从我可以看出它看起来像这一行:

DECLARE @l_query nvarchar(500) = 'SELECT TOP(1) * FROM [Automation].[dbo].[Enquiry] ORDER BY [Id] DESC';

可能会阻止某些内容或触发器本身阻止该声明。

我尝试了几件没有运气的事情。

请帮忙!

2 个答案:

答案 0 :(得分:1)

尝试使用“WITH(NOLOCK)”

SELECT TOP(1) * FROM [Automation].[dbo].[Enquiry] WITH (NOLOCK) ORDER BY [Id] DESC

答案 1 :(得分:1)

此外,您正处于交易过程中,因此至少该行被锁定,然后您发送邮件,邮件正在同一个桌面上运行一个选择顶部,您已锁定...

你可以尝试nolock作为losbear建议的,但是看到你运行的查询大概是为了显示你刚插入的记录的详细信息,并且你已经在你的触发器中插入了availble,为什么还要打扰@query

就我个人而言,我从未喜欢在交易过程中发送邮件的想法。我宁愿排队请求,提交事务,然后让一些“服务”做邮件。那将是一项相当多的工作。