【问题标题】:XACT_Abort = ON issue with Try CatchXACT_Abort = Try Catch 的 ON 问题
【发布时间】:2015-06-29 15:23:01
【问题描述】:

我有这段脚本:

Create Table AA (ID int identity(1,1), Col1 varchar(10))
Create Table BB (ID int identity(1,1), Col1 varchar(10))
GO
Create proc p6
as
insert into AA
(Col1)
Values('')

GO

Create Trigger [dbo].[TR_AA] on [dbo].[AA]
After insert
As
--Set XACT_Abort off
Select 1/0
GO

Begin Try
Begin Tran

Select @@TRANCOUNT

exec p6

Commit Tran
End Try
Begin Catch
  insert into BB(Col1)Values('')
  Select * from AA
  --Select XACT_STATE()

  Rollback Tran
End Catch

Select Count(*) from AA

GO

当我运行这段代码时,我收到了这个错误:

当前事务无法提交,无法支持 写入日志文件的操作。回滚事务。

我已经知道导致此问题的原因。

这个例子只是一个例子。但是我在触发器中有很多业务逻辑,我无法将它们移出。

所以一种解决方法是将Set XACT_Abort off 放在开头 触发。但是,通过这样做,我们会覆盖 SQL 处理触发器中的错误的默认行为。

我的问题是,如果我这样做,是否会给系统带来任何问题?

我们将不胜感激除了剥离触发逻辑之外的任何其他解决方案。

【问题讨论】:

  • 在您的 catch 语句中,您插入并发出回滚。应该反过来。无需更改XACT_ABORT
  • @ughai,问题是一旦 SQL 在触发器中生成错误,因为设置事务注定要失败,除非我们关闭该开关,否则我找不到解决它的方法。我不在乎我在 catch 块中做什么,我只需要让我的交易保持活跃。

标签: sql-server exception-handling


【解决方案1】:

如果您想让您的交易保持活跃,XACT_ABORT = OFF 应该会有所帮助。

但是,设置XACT_ABORT = OFF 并不能保证事务在所有情况下都会继续进行。这取决于错误的严重程度。

当 SET XACT_ABORT 为 OFF 时,在某些情况下,只有引发错误的 Transact-SQL 语句被回滚并且事务继续处理。根据错误的严重程度,即使 SET XACT_ABORT 为 OFF,也可能回滚整个事务。

XACT_ABORT = OFF 的另一个问题是,现在您的错误处理和持久化数据的过程在具有不同 XACT_ABORT 设置的代码中是不同的。

编辑

这些链接可能会有所帮助。

Why TRY CATCH does not suppress exception in trigger

Ignoring errors in Trigger

【讨论】:

  • 好吧,我仍然没有得到答案。但我不认为我会变得更好。对我来说,这隐含地意味着你不能在触发器中放置任何逻辑代码或一些重要的东西,基于我们的架构它不适合我们。
猜你喜欢
  • 2015-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-28
相关资源
最近更新 更多