使用THROW时,SQL Server回滚我的事务

吉尔伯特

我的一张桌子上有一个INSERT触发器,当发现重复时会发出一个throw。问题是此时我的事务似乎已隐式回滚-这是一个问题,我想控制何时回滚事务。

可以使用以下脚本重新创建问题:

CREATE TABLE xTable (
        id int identity not null
)
go
create trigger xTrigger on xTable after insert as
print 'inserting...';
throw 1600000, 'blah', 1
go

begin tran
insert into xTable default values
rollback tran

go
drop table xTable

如果您运行回滚转换-它会告诉您没有开始转换。

如果我将THROW换为“正常”异常(如SELECT 1/0),则事务不会回滚。

我检查了xact_abort标志-它已关闭。

使用SQL Server 2012并通过SSMS进行测试

任何帮助表示赞赏,谢谢。

编辑阅读完@Dan Guzman发表的文章后,我得出以下结论/总结...

SQL Server在触发器中自动将XACT_ABORT设置为ON。

我的示例(上面)没有说明我的情况-实际上,我正在使用触发器创建扩展约束。

我的用例是人为设计的,我试图在SAME单元​​测试中测试多种情况(不是现实情况,也不是好的单元测试实践)。

我对扩展约束检查的处理并在触发器中引发错误是正确的,但是没有实际情况下我不希望回滚事务。

对于特定情况,在触发器内部将XACT_ABORT OFF设置会很有用;但您的交易仍会受到一般的中止批量错误(例如死锁)的破坏。

除了历史原因,我不同意SQL Server对此的处理。仅仅因为您目前没有想要继续进行交易的情况,并不意味着可能不会出现这种情况。我希望看到一种能够设置SQL Server来维护事务完整性的方法,如果您选择的体系结构是从源头严格管理事务,即“启动事务的人必须完成它”。除了通常的故障保护之外,例如,由于系统故障而导致无法访问您的代码等。

和古兹曼

THROW将不在TRY/CATCHhttps://msdn.microsoft.com/zh-cn/library/ee677615.aspx范围内终止批处理此处的含义是不会对批处理进行进一步的处理,包括插入后的语句。您需要INSERTTRY/CATCHRAISERROR代替THROW

T-SQL错误处理是一个相当大而复杂的主题。我建议您仔细阅读Erland Sommarskog的一系列错误处理文章:http : //www.sommarskog.se/error_handling/Part1.html这里最相关的主题是Can I Prevent the Trigger from Rolling Back the Transaction? http://www.sommarskog.se/error_handling/Part3.html#Triggers从最佳实践的角度出发,如果在触发器中执行业务规则而没有回滚,则触发器不是正确的解决方案。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章