【问题标题】:How to get actual exception in SQL transaction when xact_abort is ONxact_abort 为 ON 时如何在 SQL 事务中获取实际异常
【发布时间】:2014-10-23 17:55:23
【问题描述】:

使用xact_abort ON时如何保存/检索错误状态或返回实际错误?

目前,当我执行这个存储过程时,外部事务已经启动。

begin tran
exec TestFK 2

我得到这个隐藏实际错误的通用错误

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

但是当我在没有外部事务的情况下执行时

exec TestFK 2

我得到了正确的错误。

INSERT 语句与 FOREIGN KEY 约束“FK__t2__a__3B783965”冲突。冲突发生在数据库“XXX”、表“dbo.t1”、列“a”中。

Setup Code

ALTER procedure [dbo].[TestFK]
@Id int
as
begin
    SET NOCOUNT ON        
    SET xact_abort ON  
    DECLARE @trancount INT
    SET @trancount = @@TRANCOUNT 
    begin try

        IF @trancount = 0 
            BEGIN TRANSACTION

            INSERT INTO t2 VALUES (@Id); -- Foreign key error for @Id = 2

        IF @trancount = 0 
           COMMIT TRANSACTION 
    end try
    begin catch 
      IF Xact_state() <> 0 AND @trancount = 0 
        ROLLBACK TRANSACTION 

      Exec uspInsErrorInfo -- Here I want to preserve the Error State somehow       
    end catch
END

CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY);
CREATE TABLE t2 (a INT NOT NULL REFERENCES t1(a));

INSERT INTO t1 VALUES (1);
INSERT INTO t1 VALUES (3);
INSERT INTO t1 VALUES (4);
INSERT INTO t1 VALUES (6);

【问题讨论】:

  • 呃,IF @trancount = 0 / COMMIT?为什么你关心(并且正在根据)@@TRANCOUNTBEGIN TRANSACTION 之前是什么?
  • 如果@trancount &lt;&gt; 0 则表示事务是在存储过程之外发起的,调用者将负责提交事务
  • 这不是@@NESTLEVEL 的用途吗?你也知道在 SQL Server 中并没有像嵌套事务这样的东西,对吧?您是否仔细阅读了 Erland 的文章?从这里开始:sommarskog.se/error_handling_2005.html
  • 实际上 SP 是从 C# 代码调用的,它做了两件事 1. 调用这个 SP 2. 更新 SOLR。我们需要应用程序级别的事务,以便如果SOLR 更新失败,SP 可以回滚。这个SP也是独立调用的,所以我们也需要SP中的事务。
  • 一种更简单的方法是在以一种方式与另一种方式调用过程时传递参数。

标签: sql sql-server transactions sql-server-2012 try-catch


【解决方案1】:

所以,我使用的解决方案是在这种情况下简单地删除 try/catch 块。

Since,

当 SET XACT_ABORT 为 ON 时,如果 Transact-SQL 语句引发 运行时出错,整个事务被终止并回滚。

ALTER procedure [dbo].[TestFK]
@Id int
as
begin
    SET NOCOUNT ON        
    SET xact_abort ON  
    DECLARE @trancount INT
    SET @trancount = @@TRANCOUNT 

        IF @trancount = 0 
            BEGIN TRANSACTION

            INSERT INTO t2 VALUES (@Id); -- Foreign key error for @Id = 2
            -- + some other statements
        IF @trancount = 0 
           COMMIT TRANSACTION 
END

【讨论】:

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