1

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

如果在 TransactionScope 中执行以下 sql,并且第一个删除命令出错,是否会运行第二个删除命令?(假设从父母到孩子的外键以确保失败。)

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;
    }
}

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

4

1 回答 1

1

在根据上面我自己的伪测试代码进行了一些测试之后,看起来使用 XACTABORT 和不在 TransactionScope 内的唯一区别是,如果 proc 使用 XACTABORT,它会更快地失败(对于 XACTABORT 捕获的错误)而不是 if proc 不使用 XACTABORT。TransactionScope 似乎可以捕获在其范围内执行期间的任何时候引发的异常,即使在引发这些异常之后发生了其他操作。

对于打开 XACTABORT 的存储过程,在第一次失败后没有看到任何变化,当 XACTABORT 关闭时,观察到第二条语句的变化。但是,在这两种情况下,TransactionScope 都没有完成,而是引发了异常。

所以我的问题的快速答案是:

  • 如果 XACTABORT 开启,则不会运行第二个删除语句
  • 如果 XACTABORT 关闭,则将运行第二个删除语句(以及任何后续代码)
  • 如果存储过程执行过程中遇到异常,该方法的返回值为 false
于 2009-10-01T19:10:45.613 回答