SQL ROLLBACK是否会回滚触发器的启用或禁用操作?
SQL事务回滚是否会包含触发器的启用/禁用操作?
先看你的SQL脚本:
BEGIN TRAN BEGIN TRY DISABLE TRIGGER dbo.myTrigger ON dbo.myTable; --执行需要禁用触发器的业务操作,该操作可能抛出错误 ENABLE TRIGGER dbo.myTrigger ON dbo.myTable; COMMIT; END TRY BEGIN CATCH ROLLBACK; THROW; END CATCH
当业务操作抛出错误时,你和同事的争议点在于触发器的最终状态:
- 观点1:触发器保持禁用状态,因为没执行
ENABLE TRIGGER - 观点2:触发器回到启用状态,因为
ROLLBACK会回滚事务内的所有操作,包括DISABLE TRIGGER
结论:观点2完全正确
原因说明
在SQL Server中,DISABLE TRIGGER和ENABLE TRIGGER这类DDL操作支持事务回滚。只要这些操作是在BEGIN TRAN开启的显式事务内执行的,当事务被ROLLBACK时,事务内的所有操作都会被撤销,包括触发器的禁用操作。也就是说,事务回滚后,触发器会回到执行DISABLE TRIGGER之前的启用状态,不需要在CATCH块中手动重新启用触发器。
验证测试示例
你可以通过以下脚本快速验证:
-- 创建测试表和触发器 CREATE TABLE dbo.TestTable(ID INT); GO CREATE TRIGGER dbo.TestTrigger ON dbo.TestTable AFTER INSERT AS BEGIN PRINT '触发器触发'; END; GO -- 验证触发器初始状态是启用的 SELECT name, is_disabled FROM sys.triggers WHERE name = 'TestTrigger'; -- 执行带错误的事务 BEGIN TRAN BEGIN TRY DISABLE TRIGGER dbo.TestTrigger ON dbo.TestTable; -- 模拟业务操作报错 RAISERROR('模拟业务操作报错', 16, 1); ENABLE TRIGGER dbo.TestTrigger ON dbo.TestTable; COMMIT; END TRY BEGIN CATCH ROLLBACK; THROW; END CATCH GO -- 再次查看触发器状态,is_disabled为0(启用状态) SELECT name, is_disabled FROM sys.triggers WHERE name = 'TestTrigger'; -- 清理测试对象 DROP TRIGGER dbo.TestTrigger; DROP TABLE dbo.TestTable;
执行完测试脚本后,你会看到触发器最终仍处于启用状态,证明ROLLBACK确实回滚了DISABLE TRIGGER操作。
内容的提问来源于stack exchange,提问作者F1Krazy
相关产品推荐
相关产品推荐

