2012-04-13 8 views
1

Ich hatte einige Verwirrung, die ich es löschen möchte - ich füge Werte in die Datenbank mit ADO.NET. Lassen Sie mich sagen, ich möchte 10 Artikel einfügen, wenn ich Fehler beim Einfügen von Daten des fünften Artikels erhalte, sollte es zurückrollen, was auch immer ich in die Datenbank eingefügt hatte.Rollback INSERT-Befehl in C# .NET

Ich lese gerade das Konzept der Transaktion und Rollback-Methode und versuchte auch, es in das Programm zu implementieren, aber immer noch fügen Sie 4 Artikel und geben Sie mir Fehlermeldung des fünften Elements. Die Abfrage wird nicht zurückgesetzt.

Ist Transaktion und Rollback-Methode mein Problem gelöst oder muss ich andere Alternative verwenden.

hier ist mein Code,

for (int i = 0; i < itemLength - 1; i++) 
      { 
       //--- Start local transaction --- 
       myTrans = Class1.conn.BeginTransaction(); 

       //--- Assign transaction object and connection to command object for a pending local transaction --- 
       _insertQry = Class1.conn.CreateCommand(); 
       _insertQry.Connection = Class1.conn; 
       _insertQry.Transaction = myTrans; 

       _insertQry.CommandText = "INSERT INTO Product_PropertyValue(ItemNo, PropertyNo, ValueNo) VALUES (@ItemNo, @PropertyNo, @ValueNo)"; 

       //_insertQry = new SqlCommand("INSERT INTO Product_PropertyValue(ItemNo, PropertyNo, ValueNo) VALUES (@ItemNo, @PropertyNo, @ValueNo)", Class1.conn); 

       _insertQry.Parameters.AddWithValue("@ItemNo", _itemNo[i]); 
       _insertQry.Parameters.AddWithValue("@PropertyNo", _propNo); 
       _insertQry.Parameters.AddWithValue("@ValueNo", _propValue); 

       _insertQry.ExecuteNonQuery(); 
       myTrans.Commit(); 
      } 

Kann mir jemand helfen?

+0

Wenn "Fehler" eine Ausnahme ist, haben Sie Ihre Transaktion in einem try-Block, und Rollback im Catch-Teil (und dipsosing in der letzten) (oder versuchen Sie in einer Verwendung fangen)? –

+0

Hier ist mein Code insertQry.ExecuteNonQuery(); myTransaction.Commit(); in try Block und in catch Transaction.Rollback(); –

+0

Schauen Sie sich die modifizierte Version Ihres Codes an. –

Antwort

1

zu befolgen Ich habe 2 Änderungen an Ihrem Code

1) Bewegen Sie den Begintrans() außerhalb der for-Schleife, also dass alle 10 insert-Anweisungen in einer einzigen Transaktion sind, ist das, was Sie wollen, wenn Sie wollen, einen try/catch-Block sein Atom

2) hinzugefügt, so dass Sie wieder bei Fehlern rollen können.

 //--- Start local transaction --- 
     myTrans = Class1.conn.BeginTransaction(); 
     bool success = true; 

     try 
     { 
      for (int i = 0; i < itemLength - 1; i++) 
      { 
       //--- Assign transaction object and connection to command object for a pending local transaction --- 
       _insertQry = Class1.conn.CreateCommand(); 
       _insertQry.Connection = Class1.conn; 
       _insertQry.Transaction = myTrans; 

       _insertQry.CommandText = "INSERT INTO Product_PropertyValue(ItemNo, PropertyNo, ValueNo) VALUES (@ItemNo, @PropertyNo, @ValueNo)"; 

       //_insertQry = new SqlCommand("INSERT INTO Product_PropertyValue(ItemNo, PropertyNo, ValueNo) VALUES (@ItemNo, @PropertyNo, @ValueNo)", Class1.conn); 

       _insertQry.Parameters.AddWithValue("@ItemNo", _itemNo[i]); 
       _insertQry.Parameters.AddWithValue("@PropertyNo", _propNo); 
       _insertQry.Parameters.AddWithValue("@ValueNo", _propValue); 

       _insertQry.ExecuteNonQuery(); 
      } 
     } 
     catch (Exception ex) 
     { 
      success = false; 
      myTrans.Rollback(); 
     } 

     if (success) 
     { 
      myTrans.Commit(); 
     } 

lassen Sie mich wissen, wenn das nicht funktioniert.

+0

Ist myTrans.Commit() sollte außerhalb Try-Catch-Block sein, weil es mir eine Fehlermeldung gibt. Ich habe versucht, es in letzten Block zu setzen, aber es ist immer noch der gleiche Fehler, außer dass es funktioniert hat. –

+0

Welchen Fehler haben Sie bekommen? –

+0

SqlTransaction wird nicht verwendet. Nicht behandelter SqlException-Fehler ist aufgetreten. –

2

Es klingt wie Sie versuchen, eine atomare Festschreibung zu erreichen. Es wird entweder vollständig eingefügt oder gar nicht eingefügt.

versuchen, etwas wie die folgenden

SqlTransaction objTrans = null; 
     using (SqlConnection objConn = new SqlConnection(strConnString)) 
     { 
      objConn.Open(); 
      objTrans = objConn.BeginTransaction(); 
      SqlCommand objCmd1 = new SqlCommand("insert into tbExample values(1)", objConn); 
      SqlCommand objCmd2 = new SqlCommand("insert into tbExample values(2)", objConn); 
      try 
      { 
       objCmd1.ExecuteNonQuery(); 
       objCmd2.ExecuteNonQuery(); 
       objTrans.Commit(); 
      } 
      catch (Exception) 
      { 
       objTrans.Rollback(); 
      } 
      finally 
      { 
       objConn.Close(); 
      } 

Werfen Sie auch einen Blick auf http://www.codeproject.com/Articles/10223/Using-Transactions-in-ADO-NET

0

Sie sind auf dem richtigen Weg, unterstützt ADO.NET Transaktionen so können Sie auf Fehler rückgängig zu machen.

Wenn Sie Ihren Code hier eingeben, erhalten Sie eine spezifischere Anleitung. Da jedoch Ihre Frage sehr allgemein gehalten ist, werde ich Sie ermutigen, die Vorlage von MSDN

using (SqlConnection connection = new SqlConnection(connectionString)) 
{ 
    connection.Open(); 

    // Start a local transaction. 
    SqlTransaction sqlTran = connection.BeginTransaction(); 

    // Enlist a command in the current transaction. 
    SqlCommand command = connection.CreateCommand(); 
    command.Transaction = sqlTran; 

    try 
    { 
     // Execute two separate commands. 
     command.CommandText = 
      "INSERT INTO Production.ScrapReason(Name) VALUES('Wrong size')"; 
     command.ExecuteNonQuery(); 
     command.CommandText = 
      "INSERT INTO Production.ScrapReason(Name) VALUES('Wrong color')"; 
     command.ExecuteNonQuery(); 

     // Commit the transaction. 
     sqlTran.Commit(); 
     Console.WriteLine("Both records were written to database."); 
    } 
    catch (Exception ex) 
    { 
     // Handle the exception if the transaction fails to commit. 
     Console.WriteLine(ex.Message); 

     try 
     { 
      // Attempt to roll back the transaction. 
      sqlTran.Rollback(); 
     } 
     catch (Exception exRollback) 
     { 
      // Throws an InvalidOperationException if the connection 
      // is closed or the transaction has already been rolled 
      // back on the server. 
      Console.WriteLine(exRollback.Message); 
     } 
    } 
} 
+0

Lassen Sie mich meinen Code in meiner Frage, damit Sie in der Lage zu verstehen, an welcher Stelle ich einen Fehler machen. –