使用 SqlTransaction 提交多个 SqlCommand

Commit multiple SqlCommands with SqlTransaction

我正在尝试将 SqlCommand 的列表传递到一个成员函数中,该成员函数保持与数据库的连接。

public void CommitAsTransaction(List<SqlCommand> commands) {
    SqlTransaction transaction = null;
    SqlConnection connection = null;

    try {
        connection = this.CreateSqlConnection();
        connection.Open();

        transaction = connection.BeginTransaction("TransactionID");

        foreach (SqlCommand cmd in commands) {
            cmd.Transaction = transaction;
            cmd.Connection = connection;
            cmd.ExecuteNonQuery();
        }

        transaction.Commit();
    }
    catch (Exception ex) {
        transaction.Rollback();
    }

    connection.Close();
}

这是我目前拥有的。发生错误是因为该命令似乎正在按原样执行并且从未达到 transaction.Commit(); 。我见过很多人这样做,但我不确定我做错了什么。

PS:问题是将要执行的存储过程必须全部 运行 在单个事务中,我不控制这些并且它们是加密的,原因是它们must be 运行 in a transaction 是因为他们在具有 PK 要求的 table 中创建临时记录。

您可以改用事务范围吗? 类似于:

// place this code inside CommitAsTransaction

using (TransactionScope scope = new TransactionScope())
{
     Boolean AllOK = true;
     SqlConnection connection = this.CreateSQLConnection();
     try
     {
         connection.Open()
     }
     catch (Exception e)
     {
       // deal with it how you need to
       AllOK = false;
     }

     if (AllOK)
     {
        foreach(SQlCommand cmd in Commands)
        {
            try
            {
                 cmd.Connection = connection;
                 cmd.ExecuteNonQuery();
            }
            catch (Exception e)
            {
               // Deal with it.. 
               AllOK = false;
               break;
            }
        }

        if (AllOK)
        {
           scope.Complete();
           try
           {
               connection.Close();
           }
           catch (Exception e)
           {
             // deal with it
           }
        }
    }
}

非常感谢。我最终根据其他人的综合答案自己弄清楚了,谢谢,这是我使用的代码:

public List<Models.eConnectModels.eConnStatus> CommitAsTransaction(List<SqlCommand> commands) 
{
    SqlTransaction transaction = null;
    SqlConnection connection = null;
    List<eConnStatus> ErrorList = new List<eConnStatus>();
            
    try 
    {
        connection = this.CreateSqlConnection();
        connection.Open();
                
        transaction = connection.BeginTransaction(IsolationLevel.ReadUncommitted, "TransactionID");

        foreach (SqlCommand cmd in commands) 
        {
            eConnStatus curErr = new eConnStatus();
            cmd.Transaction = transaction;
            cmd.Connection = connection;
            
            SqlParameter errorString = cmd.Parameters.Add("@oErrString", SqlDbType.VarChar);
            errorString.Direction = ParameterDirection.Output;
            errorString.Size = 8000;

            SqlParameter errorStatus = cmd.Parameters.Add("@O_iErrorState", SqlDbType.Int);
            errorStatus.Direction = ParameterDirection.Output;

            cmd.ExecuteNonQuery();
            curErr.ErrorState = (int)cmd.Parameters["@O_iErrorState"].Value;
            curErr.ErrorMessage = (string)cmd.Parameters["@oErrString"].Value;
            ErrorList.Add(curErr);
        }

        transaction.Commit();
    }
    catch (Exception ex) 
    {
        transaction.Rollback();
        connection.Close();
        throw ex;
    }
    
    connection.Close();
    return ErrorList;
}