You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 01:52:52