【发布时间】:2023-03-29 01:07:01
【问题描述】:
我有一个 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 计数将与我创建的事务中的代码不同,对吗?如果是这样,我知道这怎么可能是一个问题。存储过程调用呢?该线程是安全的和原子的吗?谢谢你的洞察力,肖恩。
标签: sql sql-server stored-procedures triggers atomic