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

设置xact_abort并尝试一起捕捉

范楚
2023-03-14

我的sp中有一个try catch块,try中只有一个insert语句。捕捉检查错误代码,如果是pk违规,如果是则做更新。但是有时我会得到“当前事务不能被提交,不能支持写入日志文件的操作。回滚事务。

在批处理结束时检测到不可提交的事务。事务被回滚了“,所以我添加了xact_abort,但后来我不断得到”EXECUTE之后的事务计数表明 BEGIN 和 COMMIT 语句的数量不匹配“,我发现了这一点。http://www.ashishsheth.com/post/2009/08/14/Set-XACT_ABORT-ON-and-TryCatch-block-in-Sql-Server-2005.aspx

如果这是真的。如果我的 try 块中存在错误且启用了 xact_abort,我的捕获代码将不会运行?

共有2个答案

那安宁
2023-03-14

让我补充一下,在这个特定场景中(尝试插入,如果PK冲突,则捕获并更新),最好使用if EXISTS(选择…)来查看行是否存在,并将更新语句放在那里。将INSERT语句放在ELSE块中。更干净。

龙凯
2023-03-14

至少在SQL SERVER 2008中,将XACT _中止设置为ON会导致跳过CATCH块的错误是不正确的:

这是我使用北风数据库尝试的代码

SET XACT_ABORT OFF
BEGIN TRY
    SELECT 1,  @@TRANCOUNT
BEGIN TRAN
    UPDATE [dbo].[Categories]
    SET Description='BLAH'
    WHERE [CategoryID]=2
    SELECT 2,  @@TRANCOUNT

    SELECT 1/0 as whoops


COMMIT
    SELECT 3,  @@TRANCOUNT

END TRY
BEGIN CATCH
    SELECT 'In Catch. Error occured', 4,  @@TRANCOUNT

     IF (XACT_STATE()) = 0
    BEGIN
        SELECT
            N'There is no transaction'

    END;


     IF (XACT_STATE()) = -1
    BEGIN
        SELECT
            N'The transaction is in an uncommittable state.' +
            'Rolling back transaction.'
        ROLLBACK TRANSACTION;
    END;

    -- Test whether the transaction is committable.
    IF (XACT_STATE()) = 1
    BEGIN
        SELECT
            N'The transaction is committable.' +
            'Committing transaction.'
        COMMIT TRANSACTION;   
    END;

END CATCH

显然,这将在命中 SELECT 1/0 语句时强制出现错误。使用 SET XACT_ABORT OFF 时,当到达 CATCH 块时,XACT_STATE() 函数返回的值为 1,从而导致代码运行该代码, 该代码使事务符合要求。当 SET XACT_ABORT 打开时,CATCH 块中返回的值为 -1,因此执行 ROLL 支持事务的代码。

这是基于:

http://msdn.microsoft.com/en-us/library/ms175976.aspx

 类似资料:
  • 我有一个存储过程似乎没有正确记录错误。 代码有错误,但 catch 块似乎未生效。 try块相当长,但错误部分很简单,并且在最后出现,所以我已经对此进行了预测。 proc失败的错误是我们的老朋友“列名或提供的值的数量与表定义不匹配”。我已经修复了这个错误 - 这是一个愚蠢的懒惰错误 - 但我感到困惑为什么我的错误日志记录过程似乎没有工作 - 没有行入到我的 ExtractsErrorLog 表中。

  • 我正在使用下面的Java(Spring 2.0)代码从Web服务读取响应: 但是,如果myUrl Web服务返回HttpStatus。错误的_请求(400),未将其分配给myResponse并引发错误,因此没有ResponseBy,我需要将请求包装在try-catch块中。这是正确的还是有办法解决这个问题?此外,这是否意味着myUrl Web服务永远不应该故意(通过编程)将myResponseOb

  • 我的项目由一个小图标组成,它在一个尺寸为25×20的网格上移动。我知道我可以用几个if/else块轻松地完成这项工作,但我想了解更多关于错误处理的知识。 我当时想的是使用try-catch,但它根本不会捕获数组索引越界异常或任何:它不会返回“error”或位置,因此它永远不会进入catch块。 我在想这样的伪代码: 实际代码:

  • 我开始在我的生产代码中使用SQL Server的tSQLt单元测试。目前,我使用Erland Sommarskog的SQL Server错误处理模式。 Erland Sommarskog建议我们始终设置XACT_ABORTON,因为只有这样SQL服务器才能以(大部分)一致的方式处理错误。 但是,这在使用tSQLt时产生了一个问题。tSQLt执行显式事务内部的所有测试。当测试完成时,整个事务回滚。这

  • 我在< code >冰咖啡脚本中使用了< code>try catch块。我调用了不存在的对象< code>a的不存在的方法< code>fake,并期望捕获错误。 但是在调用函数 a.fake()后,在控制台中抛出错误,但它没有按预期使用块。 如果我注释掉字符串<code>并等待数据库。查找“79”,将其延迟到c,d。。。 ...它按预期工作,错误被捕获。 我试图通过其他简单的异步函数调用来改变