我在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。我不确定我是否提出新问题或更新当前问题。我决定更新当前的一个。如果我要问新的,请告诉我。
答案 0 :(得分:0)
要确保transaction
roll back
始终尝试使用明确的&#39; ROLLBACK&#39; (请参阅Damien_The_Unbeliever,JodyT和Andrew的评论。所有学分归他们所有。
Kevin-Suchlicki也是对的,但就我而言,我不想使用SET XACT_ABORT ON
。