SQL Server 触发器内的存储过程调用是不是隐含线程安全和原子?

Posted

技术标签:

【中文标题】SQL Server 触发器内的存储过程调用是不是隐含线程安全和原子?【英文标题】:Is a stored procedure call inside a SQL Server trigger implictly thread safe and atomic?SQL Server 触发器内的存储过程调用是否隐含线程安全和原子? 【发布时间】:2016-05-18 15:14:52 【问题描述】:

我有一个 SQL Server 触发器。老实说,我不太确定触发器是否隐含地遵循 ACID (Atomicity, Consistency, Isolation, Durability),但我的触发器目前并没有做任何特别复杂的事情。

现在,我想从触发器中调用一个存储过程。我在存储过程调用和INSERT 语句周围有TRANSACTION

我的问题是:如果没有存储过程调用的触发器是线程安全和原子的——至少部分是由于TRANSACTION——存储过程调用是否会隐含线程安全和原子?

触发器如下所示:

CREATE TRIGGER [triggerInsert_Foobar] 
ON [Foobar]
INSTEAD OF INSERT
AS 
BEGIN
    SET NOCOUNT ON;

    -- Turns on rollack if T-SQL statement raises a run-time error
    SET XACT_ABORT ON

    -- Start new transaction
    BEGIN TRANSACTION
        -- Insert statement for trigger
        INSERT INTO Foo ( Col1, Col2 )
            SELECT 
                RTRIM ( LTRIM ( Col1 ) ), 
                Col2
            FROM 
                INSERTED

    -- Call stored procedure (takes no parameters)
    EXECUTE sp_executesql N'FoobarApp_DoSomething'

    -- Complete transaction
    COMMIT TRANSACTION
END;

感谢您的帮助。

其他问题

这个问题已经在几个回答之后准备好了(谢谢)。我提前道歉。

我的触发器和随后的存储过程调用是否遵循 ACID 原则并避免竞争条件和死锁?或者,我需要在触发器和/或存储过程中添加什么来防止竞争条件和死锁吗?

【问题讨论】:

在触发器中使用事务要非常小心。既然你没有错误处理,为什么还要麻烦?请记住,任何插入都有隐式事务。如果您的调用代码正在使用事务创建插入并且出现问题,您将得到一个未处理的异常,因为退出触发器时 tran 计数会有所不同。我会摆脱这里的事务,因为插入已经处理了这个操作的原子性质。 我相信XCT_ABORT ON 负责错误处理;如果事务失败,它会执行回滚——无需显式检查 TRANCOUNT 和回滚。关于在触发器中使用事务,您是说触发器调用的 tran 计数将与我创建的事务中的代码不同,对吗?如果是这样,我知道这怎么可能是一个问题。存储过程调用呢?该线程是安全的和原子的吗?谢谢你的洞察力,肖恩。 【参考方案1】:

底层操作和触发操作被视为原子操作。他们都在一个事务中提交。来自the documentation:

触发器和触发它的语句被视为单个事务...

请注意,触发器(以及 SP 将调用)不会看到触发触发器的表更改。它还没有提交。

【讨论】:

谢谢。有趣的。那么,INSERT 语句在触发器完成之前不会真正提交?这意味着如果我的存储过程依赖于表更改,那么这可能是放置存储过程的错误位置。 @user3621633,您必须将值从 INSERTED 传递到 SP,这听起来是个坏主意。 这有点个人喜好/风格,但我倾向于避免触发因素。检查表格时,它们很容易被忽略。对于您正在做的事情,只需调用存储过程并让它更新表以及您在那里所做的任何事情。 @user3621633:如果您需要检查INSERT 语句插入的数据,您可能应该使用AFTER INSERT 触发器,而不是INSTEAD OF INSERT 触发器。在这种情况下,您的触发器在插入操作完成后执行,但仍在该INSERTstatement 的事务中。如果您不喜欢看到的内容,您可以调用 ROLLBACK 并中止 INSERT 事务以停止它。 这是我想要确认的信息。我有一个场景,触发器正在影响我不想要的记录。他们的回答是……脏读……

以上是关于SQL Server 触发器内的存储过程调用是不是隐含线程安全和原子?的主要内容,如果未能解决你的问题,请参考以下文章

SQL-Server:是不是有相当于一般存储过程执行的触发器

SQL Server 触发器

SQL Server 触发器

SQL Server 触发器

SQL server 2008创建触发器实例

SQL Server 触发器