Domanda

  1. Ho SQL Server 2000, non supporta MultipleActiveResults .
  2. Devo fare più inserimenti, ed è fatto con una connessione per inserimento.
  3. Voglio iniziare una transazione prima di tutti gli inserimenti e finirla dopo tutti gli inserimenti.
  4. Come posso farlo?
È stato utile?

Soluzione

Qual è il motivo per cui non usi una connessione e più comandi (in realtà un comando ricreato in loop)? Forse questa soluzione funzionerà per te:

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

Vedi anche
Transazioni SQL Server - ADO.NET 2.0 - Commit and Rollback - Utilizzo Dichiarazione - IDisposable

Altri suggerimenti

Non hai specificato se stai usando .NET 2.0, ma farò questo presupposto. Il codice di esempio C # 3.0 è elencato di seguito:

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

Se una delle istruzioni DB fallisce, ts.complete non verrà mai raggiunto e la transazione verrà automaticamente ripristinata alla fine dell'istruzione using. Tuttavia, un avvertimento a questo approccio è che finirai per sfruttare il DTC se usi connessioni multiple, il che significa prestazioni più lente.

Modificato per cambiare SqlTransaction in TransactionScope

Un esempio di forzare una singola connessione SQL per evitare l'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();
}

Le transazioni vengono create su una connessione e non hanno alcun ambito oltre la connessione su cui sono state create, quindi non puoi fare ciò che stai chiedendo. Refactor in modo da poter eseguire gli inserimenti in sequenza su una connessione anziché simultaneamente o implementare un meccanismo diverso per ottenere il rollback (ad esempio una tabella di chiavi inserite che può essere utilizzata come ricerca per eliminare i record inseriti se si verifica un errore in seguito nella processo)

Non credo che una transazione possa estendersi su più connessioni.

Qual è il ragionamento per fare gli inserti multipli in connessioni separate? Penso che li vorresti normalmente in una singola connessione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top