当前位置: 首页 > 知识库问答 >
问题:

如何正确使用SETXACT_ABORT

阎建中
2023-03-14

我们最近被空降到一个代码非常糟糕的新ETL项目。我手里有一个包含700行和各种更新的查询。

我想调试它与SETXACT_ABORTON;和目标是回滚一切,如果只有一个事务失败。

但是我找到几种方法将其存档在堆栈溢出上,如下所示:

BEGIN TRANSACTION;
BEGIN TRY

-- Multiple sql statements goes here

COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
END CATCH

或者这个:

BEGIN TRY
BEGIN TRANSACTION

-- Multiple sql statements goes here

COMMIT TRANSACTION
END TRY
BEGIN CATCH
PRINT(ERROR_MESSAGE())
ROLLBACK TRANSACTION
END CATCH

这些都没有使用SETXACT_ABORTON;

我不明白,SETXACT_ABORTON是否与使用BEGIN TRY BEGIN TRANSACTION相同?

我可以只使用:

SET XACT_ABORT ON;

-- Multiple sql statements goes here

并摆脱所有:

BEGIN TRANSACTION;
BEGIN TRY

?

此外,我应该使用BEGIN TRANSACTION然后BEGIN TRY还是相反?

共有3个答案

慕承恩
2023-03-14

如果在上有<code>XACT_ABORT,则无需手动捕获任何错误,除非您正在进行错误日志记录XACT_ABORT将导致所有错误导致交易失败并回滚。

你所需要的只是

sql prettyprint-override">SET XACT_ABORT ON;
BEGIN TRAN;
--do stuff
COMMIT;

如果只有一个语句,那么您甚至不需要 BEGIN TRAN;“提交”;

金珂
2023-03-14

感谢您@George梅诺蒂斯提供的资源。

我在这里发布我的实际解决方案

SET XACT_ABORT ON;
BEGIN TRY
      BEGIN TRANSACTION;


      -- Multiple sql statements goes here


      COMMIT TRANSACTION;
END TRY
BEGIN CATCH
      IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
      THROW;
END CATCH;
GO

SET XACT_ABORT OFF;
韦澄邈
2023-03-14

这是不一样的。它决定何时抛出错误。

您应该始终使用SETXACT_ABORTON,因为它更一致;几乎总是,错误会停止执行并抛出错误。否则,一半的事情抛出错误,另一半继续执行。

在Erland Sommarskog的网站上有一篇关于这个主题的文章,如果你在这一点上,你会看到一个描述这种奇怪行为的表格。总之,我推荐错误处理的一般模式,因为它有很好的文档记录,并为您提供了根据自己的文档进行调整的机会。

 类似资料:
  • 问题内容: 我只想检索UserAccount类中的某些列,所以我有以下代码: 我得到了空值作为回报。但是,如果我注释掉setProjections,我将获得具有所有属性的用户。在这种情况下,如何正确使用setProjection? 问题答案: 它返回一个Object数组,因此代码应为:

  • 问题内容: 我不知道我在哪里错了:/。当我运行这段代码时,我得到的只是一个空白元素。我似乎无法让insertRule方法执行任何操作(甚至不会产生错误)。我想念什么吗? 问题答案: 这有点令人困惑,但是您的代码确实可以工作,只是您看不到返回的XML树中插入的规则。 为了验证您的代码是否有效,您可以执行两个测试: 运行上面的代码片段,您可以看到CSS规则确实适用。并且属性也在控制台中更改。 当浏览器

  • 问题内容: 如何使用从类路径中查找递归资源? 例如 在“目录”中查找所有资源:想象一下 不幸的是,这只会检索到恰好该“目录”。 所有资源都已命名(递归) 但这返回一个空。 还有一个额外的问题:与有什么不同? 问题答案: 没有办法递归搜索类路径。您需要知道资源的完整路径名才能以这种方式检索它。该资源可能位于文件系统中的目录中,也可能位于jar文件中,因此它不像执行“类路径”的目录列表那样简单。您将需

  • 问题内容: 我最近开始使用ScriptManager。我有一个通过JavaScript填充的ASP.NET DropDownList控件。但是,我正在使用事件验证。因此,如果我不使用下拉菜单中的“ RegisterForEventValidation”调用,则会遇到以下错误。我怎么知道在第二个参数中设置什么值(我有“值”)?我正在通过JavaScript填充下拉列表,因此我不知道后面的代码中包含哪

  • 我正在尝试正确地使用ByteBuffer和BigEndian字节顺序格式。。 我有几个字段,我试图把它存储在Cassandra数据库之前放在一个单一的ByteBuffer中。 我将要写入Cassandra的字节数组由三个字节数组组成,如下所述- 现在,我将写,和一起到一个字节数组和由此产生的字节数组我将写入Cassandra,然后我将有我的C程序来检索它字节数组数据从Cassandra,然后反序列

  • 问题内容: 我在用 : Node.js Express 4.0 Passport.js Google OAuth 2身份验证 对于每个用户,我将其Google个人资料中的一些信息(电子邮件等…)存储在MySQL数据库中(我对此技术没有选择),访问和刷新令牌以及用户在提供信息时提供的其他信息他在我的应用上注册。 我已经看到了password.js的不同用法,特别是关于该信息在会话中的存储方式。 在p