【问题标题】:How to set "SET XACT_ABORT ON " in a SQL Server transaction?如何在 SQL Server 事务中设置“SET XACT_ABORT ON”?
【发布时间】:2011-11-05 20:50:34
【问题描述】:

我想在带有事务的 SQL Server 2008R2 存储过程中设置SET XACT_ABORT ON,所以在创建脚本中进行:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET XACT_ABORT ON
GO

CREATE PROCEDURE MyProc
AS
BEGIN TRAN  
    ... 
IF @@ERROR <> 0
BEGIN
    GOTO Done
END 
    ... 
IF @@ERROR <> 0
BEGIN
    GOTO Done
END 
COMMIT TRAN     
Done:
IF @@ERROR <> 0
BEGIN
    ROLLBACK TRAN
END
GO

成功创建后,我通过单击“修改”存储过程选项检查事务,并在生成的ALTER PROCEDURE 脚本中看不到SET XACT_ABORT ON 行:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE MyProc
AS
BEGIN TRAN
...

我哪里错了或者有什么诀窍?如何正确定义SET XACT_ABORT ON

【问题讨论】:

  • 您没有在过程定义中包含SET 语句。就像你在 2008 年一样,你应该看看TRY ... CATCH
  • @Martin Smith:您的意思是根本不包括SET XACT_ABORT ON,而是通过TRY..CATCH 捕获错误并明确ROLLBACK 一个事务?
  • 请参阅this answer 和下面的 cmets 以获得关于此的良好讨论。我绝对不会费心在 SQL Server 2008 上测试 @@ERROR,因为当 TRY...CATCH 可用时您的代码正在执行此操作。只是提到XACT_ABORTTRY 块中具有不同的效果。
  • @Martin Smith:谢谢,马丁!我会注意的。

标签: sql-server sql-server-2008 tsql stored-procedures transactions


【解决方案1】:

您通常将xact_abort 设置为存储过程主体的一部分:

CREATE PROCEDURE MyProc
AS
SET XACT_ABORT ON
BEGIN TRAN  
....

从创建过程的会话中记住了两个“特殊”设置。 Explanation from MSDN:

存储过程使用执行时指定的 SET 设置执行 SET ANSI_NULLS 和 SET QUOTED_IDENTIFIER 除外。已存储 指定 SET ANSI_NULLS 或 SET QUOTED_IDENTIFIER 的过程使用 在存储过程创建时指定的设置。如果在一个内部使用 存储过程,任何 SET 设置都将被忽略。

因此,当您创建存储过程时,SQL Server 会将 QUOTED_IDENTIFIER 选项从连接复制到过程定义。目标是具有不同 QUOTED_IDENTIFIER 设置的其他人仍然获得过程作者预期的行为。

XACT_ABORT 的情况并非如此。

【讨论】:

  • 为什么你的 sql 示例使用SET XACT_ABORT ON 并且还使用事务?将XACT_ABORT 设置为ON 的目的不就是让整个过程原子化吗?为什么还需要交易?
  • 好的,我看到作者在他的代码示例中已经有了它。不过,我之前的说法准确吗?
【解决方案2】:

您没有提到您是否使用 SQL Management Studio,但如果您使用并在现有存储过程上单击“修改”(我假设这是您所做的),那么 MS 只会生成一个样板脚本基于现有存储过程的内容。

您可以考虑在一个单独的脚本文件中定义您的存储过程,该脚本文件执行和 ALTER PROCEDURE,以及您想要的 sproc 之外的任何其他选项(例如 SET XACT_ABORT ON)。这样你就有了更多的控制权,并且可以只执行脚本来更新存储过程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多