RAISERROR严重级别16是回滚交易

时间:2017-06-29 20:10:10

标签: sql-server sql-server-2008-r2

我有一个问题是插入更新后触发器。测试代码如下。问题是当这个表上的事务开始时,它会回滚。

经过大量的在线研究后,似乎每个人都处于积极状态,事实并非如此。无论如何,服务器方面有什么设置我错过了吗?

我还将sp_settriggerorder()添加到第一个触发器,最后命名一个有问题的触发器。

我还注意到,禁用以下触发器可以完成交易。

低于11的严重性不是一个选项,因为它会在客户端应用程序中提示一个丑陋的警告,强制用户“扩展”#34;选择。

严重级别11到16都给了我这个问题。

USE [Test]
GO
/****** Object:  Trigger [dbo].[co_bln_AfterIup]    Script Date: 06/29/2017 14:43:12 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER TRIGGER [dbo].[co_bln_AfterIup]
ON [dbo].[co_bln]
AFTER INSERT,UPDATE

AS

IF 1 = 1

RAISERROR('test error',16,1)

2 个答案:

答案 0 :(得分:1)

简短回答

1#在触发执行开始时设置SET XACT_ABORT

2#做一些DML(插入/更新/删除)

3#设置条件以触发RAISERROR,消息和严重性低于18

4#结果将提交带有引发错误的事务

更长的答案

在SQL Server中有两种处理错误的方法,一种是使用RAISERROR而另一种是使用THROW。您更喜欢哪一个取决于进一步的解释

使用throw你不能指定严重性,你可以使用RAISERROR 使用更高(大于18)的严重性,您可以终止用户连接,这不是您可以使用throw

执行的操作

还可以在显式事务(BEGIN / END)中指定RAISERROR THROW不能(必须使用TRY / CATCH块)。

这里重要的是连接这两个错误处理程序的东西是XACT_ABORT 通过指定XACT_ABORT,您正在定义事务行为

在单个事务中,某些事务可能会失败,并且其中一些不会,取决于XACT_ABORT是ON还是OFF,这些成功事务中的一些可能会执行而其他事务不会执行,这通常是你的事情如果你想保持一致的数据库,不想这样做 有关XACT_ABORT的更多信息,请阅读here

现在这与你的错误处理程序有什么关系?

如果在事务SET SET XACT_ABORT OFF的指令处指定,则RAISERROR错误处理程序将不会回滚事务,并且您之前执行的任何操作都将反映到数据库中。 您必须使用显式ROLLBACK事务或启用XACT_ABORT

来防止这种情况

如果要使用TRY / CATCH块,并进行一些错误处理,可以使用其中任何一个。无论何时调用RAISERROR或THROW,您都将直接转移到CATCH块。但请记住,即使您在catch块中,如果XACT_ABORT为OFF并且您使用的是没有ROLLBACK命令的RAISERROR,那么无论如何都将完成该事务。 如果您使用THROW,它将立即回滚

然而,XACT_ABORT开启或关闭对THROW处理程序没有影响,并将按预期执行(回滚所有更改)

另请注意,即使XACT_ABORT为OFF,您仍然可以使用18以上的严重性回滚事务

因此,根据您想要达到的目标,您可以选择最适合您的方式。遵循标准,THROW是最好的,它更新但是如果你想只显示警告 - 回到简短回答

答案 1 :(得分:0)

如果您不希望RAISERROR结束交易,您可以在TRY/CATCH区块中围绕RAISERROR周围的语句。或者您可以使用TRY / CATCH块包围INSERT / UPDATE语句,该语句触发触发器。

来自RAISERROR文档(备注):

  

当RAYERROR在TRY块中以11或更高的严重性运行时,它会将控制权转移到相关的CATCH块。

严重程度在11到20之间的RAISERROR应该将控制转移到catch块,如果你不写,则不一定会中止交易。

在没有看到所有代码的情况下,我猜测你的程序的某些部分正在回滚事务,作为对触发器中引发的错误的响应。