Raiserror severity 16不会回滚触发器

时间:2014-07-21 14:41:53

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

我在SQL Server 2008上运行了一个数据库。

我有一个触发器,我在其中引发严重程度为16的错误。当我测试触发器时出现错误但操作没有回滚,即我在表中有额外的行。我无法理解为什么会这样,因为严重性16会导致回滚。我们还在其他触发器中使用了该约定,它终止了触发器并导致回滚。

该表还有另一个不允许删除行的触发器。

这是触发器:

    ALTER TRIGGER dbo.trg
    ON dbo.tbl
    AFTER INSERT, UPDATE
    AS
    BEGIN
      IF (@@ROWCOUNT > 0)

        IF ((SELECT COUNT(SDS.ID) AS Count0 FROM dbo.tbl SDS WHERE SDS.IsIdleTimeReferred = 0) <> 1) OR 
           ((SELECT MAX(SDS.CreatedDate) FROM dbo.tbl SDS WHERE SDS.IsIdleTimeReferred = 0) <
             (SELECT MAX(SDS.CreatedDate) FROM dbo.tbl SDS WHERE SDS.IsIdleTimeReferred = 1))
        BEGIN
          --IF @@TRANCOUNT > 0 ROLLBACK
          RAISERROR('Only one record with value IsIdleTimeReferred=0 must exist and it must be the last one', 16, 1);
        END;
    END;

当我取消注释@@TRANCOUNT时,操作行为正确。

tbl由3列组成:

[ID], [IsIdleTimeReferred], [CreatedDate]

我无法弄清问题在哪里。对我来说,代码设计正确。

有什么想法吗?

编辑:

好的,我同意Severity 16不会在触发器中回滚事务。所以我实现了以下代码(触发器为AFTER INSERT, UPDATE):

BEGIN
  IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
  RAISERROR('Does not allow modifications in the past', 16, 1);
  RETURN;
END;

此代码不会在触发器中回滚事务。如果我切换行,先切换RAISERROR然后ROLLBACK,则不会回滚更改。

为什么会这样?

P.S。我不确定我是否提出新问题或更新当前问题。我决定更新当前的一个。如果我要问新的,请告诉我。

1 个答案:

答案 0 :(得分:0)

要确保transaction roll back始终尝试使用明确的&#39; ROLLBACK&#39; (请参阅Damien_The_UnbelieverJodyTAndrew的评论。所有学分归他们所有。 Kevin-Suchlicki也是对的,但就我而言,我不想使用SET XACT_ABORT ON