SQL 没有回滚整个 SqlCommand 的错误

SQL error not rolling back entire SqlCommand

我一直在将 set xact_abort on 放入 SQL 命令语句中,并注意到它不会在我的 C# SqlCommand 中回滚更新、插入等错误。摘自 this post. The MSDN 指出:

When SET XACT_ABORT is ON, if a Transact-SQL statement raises a run-time error, the entire transaction is terminated and rolled back.

我的 SQl 查询的一般格式是:

set xact_abort on
INSERT INTO Table1
UPDATE Table2
UPDATE Table3
UPDATE Table4
--Finally
SELECT someValue

我注意到我的 SQL 命令出错时没有被回滚。这种情况下的特定错误是一个参数的数据长度超过了指定的列长度。我正在使用 SqlCommandSqlParameter 创建 SQL 查询。

我不打算处理 SQL 中的异常,但重要的是任何错误都不会对数据库进行任何更改。

典型的错误包括:列不存在、数据类型错误、数据会因长度而被截断等。

我应该使用 set xact_abort on 以外的东西吗?提前致谢!

您从 MSDN 引用的声明是正确的:将 XACT_ABORT 设置为 ON任何 错误将中止批处理并且 roll-back任何活跃的交易。这里的困惑在于,在SQLServer中,默认情况下每条语句本身就是一个Transaction。如果你想将多个语句组合成一个显式事务,那么你需要使用 BEGIN TRAN;COMMIT;。以下示例说明了此行为:

运行这个:

SET XACT_ABORT ON;
CREATE TABLE #Bob (ID INT);

INSERT INTO #Bob (ID) VALUES (1);

BEGIN TRAN;

INSERT INTO #Bob (ID) VALUES (2);
INSERT INTO #Bob (ID) VALUES (3);
INSERT INTO #Bob (ID) VALUES (4 / 0);

COMMIT TRAN;

然后 运行 这分开(因为上面的语句中的错误将中止整个批处理 - 由于使用 XACT_ABORT ON - 所以 SELECT 将永远不会执行如果您尝试同时 运行 SELECT):

SELECT * FROM #Bob;

它将 return 包含 1 的单行,因为该语句由其自身执行,而不是在显式事务中执行。一旦将 BEGIN TRAN;COMMIT TRAN; 语句添加到您的代码中,它就会按您预期的那样工作。

从 C# 代码处理事务的一种模式如下:

try
{
    var connection = new SqlConnection(connectionString);
    connection.Open();

    var trans = connection.BeginTransaction(); 

    using (var command = connection .CreateCommand())
    {
        command.Transaction = trans;
        command.CommandText = "...";
        command.ExecuteNonQuery();
    }

    // other commands may be defined here
    // command can be included or excluded from transaction (do not set Transaction property)

    // commits the transaction
    trans.Commit(); 
}
// best practice is to catch specific exception types like `SqlException`
catch (Exception ex) //error occurred
{
    trans.Rollback();
    // log error somewhere
}
finally
{
    // execute no-matter what
}

这种模式有以下优点:

  1. 无需担心SET XACT_ABORT(默认关闭)
  2. 更好的异常处理

注:您可能对Unit of Work pattern

感兴趣