Pergunta

  1. Eu tenho SQL Server 2000, não suporta MultipleActiveResults .
  2. Eu tenho que fazer várias inserções, e é feito com uma conexão por inserção.
  3. Eu quero iniciar uma transação antes de todas as inserções e terminá-lo depois de todas as inserções.
  4. Como posso fazê-lo?
Foi útil?

Solução

O que é a razão que você não use uma conexão e comandos múltiplas (na verdade um comando recriado em circuito)? Talvez esta solução irá trabalhar para você:

   public static void CommandExecNonQuery(SqlCommand cmd, 
       string query, SqlParameter[] prms)
    {
        cmd.CommandText = query;
        cmd.Parameters.AddRange(prms);
        cmd.ExecuteNonQuery();
        cmd.Parameters.Clear();
    }

    static void Main(string[] args)
    {
        string insertQuery = 
           @"INSERT TESTTABLE (COLUMN1, COLUMN2) " + 
             "VALUES(@ParamCol1, @ParamCol2)";
        using (SqlConnection connection = 
          new SqlConnection(connectionString))
        {
            using (SqlCommand command = 
              connection.CreateCommand())
            {
                SqlTransaction transaction = null;
                try
                {
                    // BeginTransaction() Requires Open Connection
                    connection.Open();

                    transaction = connection.BeginTransaction();

                    // Assign Transaction to Command
                    command.Transaction = transaction;
                    for (int i = 0; i < 100; i++)
                        CommandExecNonQuery(command, insertQuery, 
                          new SqlParameter[] { 
                            new SqlParameter("@ParamCol1", i), 
                            new SqlParameter("@ParamCol2", i.ToString()) });
                    transaction.Commit();
                }
                catch
                {
                    transaction.Rollback();
                    throw;
                }
                finally
                {
                    connection.Close();
                }
            }
        }
    }

Veja também
SQL Server Transações - ADO.NET 2.0 - Commit e Rollback - Usando declaração - IDisposable

Outras dicas

Você não especificou se você estiver usando o .NET 2.0, mas eu vou fazer essa suposição. C # 3.0 código de amostra é listado abaixo:

using (var tx = new TransactionScope()) {
    // Execute multiple DB statements inside here
    ts.Complete();
}

Se alguma das declarações DB falhar, o ts.complete nunca será alcançada e a transação será revertida automaticamente no final da instrução using. No entanto, uma ressalva a esta abordagem é que você vai acabar aproveitando o DTC se você usar várias conexões, o que significa um desempenho mais lento.

editado para mudar SqlTransaction para TransactionScope

Um exemplo de forçar uma única conexão SQL para evitar o uso do DTC:

using (var tx = new TransactionScope())
using (var db = new SqlConnection(connString)) {
    // Command 1
    using (var cmd = db.CreateCommand()) {
        cmd.CommandText = "select...";
        using (var reader = cmd.ExecuteReader()) {
           // Process results or store them somewhere for later
        }
    }

    // Command 2
    using (var cmd = db.CreateCommand()) {
        cmd.CommandText = "select...";
        using (var reader = cmd.ExecuteReader()) {
           // Process results or store them somewhere for later
        }
    }

    // Command 3
    using (var cmd = db.CreateCommand()) {
        cmd.CommandText = "select...";
        using (var reader = cmd.ExecuteReader()) {
           // Process results or store them somewhere for later
        }
    }
    tx.Complete();
}

Transações são criadas em uma conexão e não têm escopo para além da conexão que eles são criados em que você não pode fazer o que você está pedindo. Refactor para que você possa executar as inserções sequencialmente em uma conexão em vez de simultaneamente ou implementar um mecanismo diferente para conseguir o desmantelamento (por exemplo, uma tabela de chaves inseridas que pode ser usado como um olhar-se para apagar registros inseridos, se for encontrado um erro no final do processo)

Eu não acho que uma transação pode abranger várias conexões.

Qual é o raciocínio para fazer as várias inserções em conexões separadas? Eu acho que você quer que eles em uma única conexão normalmente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top