代码之家  ›  专栏  ›  技术社区  ›  Matt Mills

XACT_在TransactionScope内中止以进行简单的错误处理

  •  1
  • Matt Mills  · 技术社区  · 15 年前

    这个问题试图探索SQL Server 2000中TransactionScope和xact_abort之间的交互所涉及的语义。

    如果在TransactionScope中执行以下sql,并且第一个delete命令出错,是否会运行第二个delete命令?(假定父级到子级之间存在外键,以确保失败。)

    create procedure test
        @id int
    as
    set xact_abort on
    -- no explicit transaction is created
    
    -- if this fails
    delete from dbo.[parentTable]
    where id = @id
    
    -- will this run?
    delete from dbo.[childTable]
    where id = @id
    

    public bool TryTestStoredProcedure()
    {
        try 
        {
            using (TransactionScope t = new TransactionScope())
            {
                MethodThatRunsTestStoredProcedure();
                t.Complete();
                return true;
            }
        }
        catch
        {
            return false;
        }
    }
    

    如果存储过程中的第一个delete语句失败,该方法的返回值是多少?如果第二条delete语句失败了怎么办?

    1 回复  |  直到 15 年前
        1
  •  1
  •   Matt Mills    15 年前

    在基于上面我自己的伪测试代码进行了一些测试之后,使用XACTABORT和不在TransactionScope中的唯一区别似乎是,如果进程使用XACTABORT,那么失败的时间(对于XACTABORT捕获的错误)要比不使用XACTABORT快。TransactionScope似乎可以捕获在其范围内执行期间的任何时间点引发的异常,即使在引发这些异常之后发生了其他操作。

    对于启用XACTABORT的存储过程,在第一次失败后没有看到任何更改,当XACTABORT关闭时,观察到第二条语句的更改。但是,在这两种情况下,TransactionScope都没有完成,而是抛出了一个异常。

    • 如果XACTABORT处于关闭状态,则将运行第二条delete语句(以及任何后续代码)
    • 如果在执行存储过程期间遇到异常,则该方法的返回值将为false