代码之家  ›  专栏  ›  技术社区  ›  M. Afrashteh

在MS SQL Server中,什么类型的错误导致xact_状态为1?

  •  2
  • M. Afrashteh  · 技术社区  · 6 年前

    基于Microsoft文档关于Try…Catch,当xact_状态为-1时,事务是不可提交的( TRY...CATCH (Transact-SQL) ):

    不可提交的事务和xact_状态

    如果在try块中生成的错误导致当前 要失效的事务,该事务被分类为 不可提交的事务。 通常结束事务的错误。 在try块外部导致事务输入不可提交的 在try块中发生错误时的状态。 不可承诺的 事务只能执行读取操作或回滚 交易。该事务无法执行任何Transact-SQL 将生成写操作或提交的语句 交易。xact_state函数返回-1的值,如果 事务被分类为不可提交的事务。什么时候? 批处理完成后,数据库引擎将回滚任何活动的 不可提交的交易。如果在 事务进入不可提交状态,批处理完成后, 将向客户端应用程序发送错误消息。这个 指示检测并回滚了不可提交的事务 回来。

    如果我理解正确,每一个停止try块连续性并进入catch块的错误都会导致xact_状态为-1(当xact_abort打开时),但在上述文档的示例C中,检查它是否为1:

    . …结束尝试开始捕获 --执行错误检索例程。
    执行USP获取错误信息;

    -- Test XACT_STATE:  
        -- If 1, the transaction is committable.  
        -- If -1, the transaction is uncommittable and should   
        --     be rolled back.  
        -- XACT_STATE = 0 means that there is no transaction and  
        --     a commit or rollback operation would generate an error.  
    
    -- Test whether the transaction is uncommittable.  
    IF (XACT_STATE()) = -1  
    BEGIN  
        PRINT  
            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  
        PRINT  
            N'The transaction is committable.' +  
            'Committing transaction.'  
        COMMIT TRANSACTION;     
    
    END; END CATCH; GO
    

    我的问题是:

    这是错误的例子吗?如果不是,什么样的错误会导致catch块中的xact_状态为1(可提交)?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Geoff Hacker    6 年前

    SQL Server可以容忍事务中的某些错误,而不必将其标记为不可提交。例如,选择1/0将导致错误,但不会强制事务进入不可提交状态。(引自 https://docs.microsoft.com/en-us/azure/sql-data-warehouse/sql-data-warehouse-develop-transactions )

    实际上,除非启用xact_abort,否则几乎所有非致命错误都将产生xact_状态1(pk冲突、数据类型转换、约束冲突等)。(这是从 https://www.sqlservercentral.com/Forums/Topic1109613-1550-1.aspx )