如何回滚已使用SqlTransaction执行的所有SqlCommand?

问题描述 投票:0回答:2

缺少的东西,我有以下代码:

public void Execute(string Query, params SqlParameter[] Parameters)
{
    using (var Connection = new SqlConnection(Configuration.ConnectionString))
    {
        Connection.Open();
        using (var Command = new SqlCommand(Query, Connection))
        {
            if (Parameters.Length > 0)
            {
                Command.Parameters.Clear();
                Command.Parameters.AddRange(Parameters);
            }
            Command.ExecuteNonQuery();
        }
    }
}

对于不同的查询,该方法可能被调用2或3次,但方式相同。

例如

  1. 插入员工
  2. 插入员工证书
  3. [另一张桌子上员工的更新程度[此处可能导致失败。例如]

如果Point [3]失败,则不应执行所有已提交的命令,而必须回滚。

我知道我可以将SqlTransaction放在上面并使用Commit()方法。但是如果失败,第三点呢?我认为只有第3点会回滚,而其他1,2点不会?如何解决这个问题,我应该怎么做?

我应该使用SqlCommand []数组??我应该做什么。

c# .net ado.net ado sqlclient
2个回答
0
投票
using (var connection = new SqlConnection(Configuration.ConnectionString)) { SqlCommand command = connection.CreateCommand(); SqlTransaction transaction; connection.Open(); transaction = connection.BeginTransaction("Transaction"); command.Connection = connection; command.Transaction = transaction; try { if (Parameters.Length > 0) { command.Parameters.Clear(); command.Parameters.AddRange(Parameters); } command.ExecuteNonQuery(); transaction.Commit(); } catch (Exception e) { try { transaction.Rollback(); } catch (Exception ex2) { //trace } } }

0
投票
有几种方法可以做到。

该方法可能涉及更改最少的代码,并涉及最少的复杂性是将多个SQL语句链接到单个查询中。为运行多个语句(包括QueryBEGIN TRANSACTION和(如果需要)COMMIT)的ROLLBACK参数构建字符串是完全可以的。基本上,在您的C#代码中构建整个存储过程。这也具有使程序更易于使用版本控制的好处。

但是它仍然感觉有点破旧。

减少这种影响的一种方法是标记我的Execute()方法

private。然后,我将在类中为运行的每个查询提供一个附加方法。这样,长的SQL字符串就被隔离了,使用数据库时感觉更像是使用本地API。对于更复杂的应用程序,它可能是一个完整的单独程序集,其中的核心方法是internal

但是您也可以扩展持有Execute()方法的类型以支持交易。这里的技巧是将这种类型设置为static是很常见的,但是支持事务需要重新使用连接对象,这意味着实例和实现IDisposable都是如此。
© www.soinside.com 2019 - 2024. All rights reserved.