Pregunta

  1. Tengo SQL Server 2000, no es compatible con MultipleActiveResults .
  2. Tengo que hacer varias inserciones, y se hace con una conexión por inserción.
  3. Quiero comenzar una transacción antes de todas las inserciones y finalizarla después de todas las inserciones.
  4. ¿Cómo lo hago?
¿Fue útil?

Solución

¿Cuál es la razón por la que no usa una conexión y varios comandos (en realidad, un comando recreado en bucle)? Tal vez esta solución funcione para usted:

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

También vea
Sql Server Transactions - ADO.NET 2.0 - Commit and Rollback - Using Declaración - IDisponible

Otros consejos

No especificó si está utilizando .NET 2.0, pero haré esa suposición. El código de muestra de C # 3.0 se enumera a continuación:

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

Si cualquiera de las declaraciones de la base de datos falla, ts.complete nunca se alcanzará y la transacción se retrotraerá automáticamente al final de la declaración de uso. Sin embargo, una advertencia a este enfoque es que terminará aprovechando el DTC si usa varias conexiones, lo que significa un rendimiento más lento.

Editado para cambiar SqlTransaction a TransactionScope

Un ejemplo de forzar una conexión SQL única para evitar el uso del 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();
}

Las transacciones se crean en una conexión y no tienen ningún alcance más allá de la conexión en la que se crean, por lo que no puede hacer lo que está pidiendo. Refactorizar para que pueda ejecutar las inserciones secuencialmente en una conexión en lugar de simultáneamente o implementar un mecanismo diferente para lograr la reversión (por ejemplo, una tabla de claves insertadas que se puede usar para buscar registros insertados si se encuentra un error más adelante en la proceso)

No creo que una transacción pueda abarcar varias conexiones.

¿Cuál es el motivo para realizar las inserciones múltiples en conexiones separadas? Pensaría que los querrías en una sola conexión normalmente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top