2016-04-13 2 views
1

Ich untersuche ein intermittierendes Auftreten von Devart.Data.Linq.ChangeConflictException: Row not found or changed.* Not * bekomme ChangeConflictException mit Devart

Ich habe den Devart Artikel auf concurrency conflicts gelesen, und nur als Ausgangspunkt versuche ich, einen Concurrency-Konflikt zu reproduzieren. Mit den enthaltenen MS-basierten LINQ-Klassen ist dies einfach zu bewerkstelligen (mit der folgenden Code-Struktur wird dies erfolgreich durchgeführt). Aber selbst wenn ich ihrem Beispiel in dem Artikel folge, kann ich keine Ausnahme erzeugen. Ich habe

versucht
  • Verwendung sowohl eine ADO genau parametrierte Abfrage wie in ihrem Artikel gezeigt
  • die vereinfachte ADO Abfrage unten (nicht besorgt über Injection-Angriffe während dieses Tests)
  • Mit LinqConnect mit einem neuen Kontext (auch in ihrem Artikel vorgeschlagen).
  • Anhalten der Ausführung mit einem Debugger und manuelle Aktualisierung der Tabelle mit MySQL Workbench.

bin ich mit der Testcode Dies wird:

public static void MySqlTest() 
{ 
    using (MySqlDataContext db = new MySqlDataContext()) 
    { 
     Customer customer = db.Customers.First(c => c.Username.Equals("ian2")); 

     MySqlAdoChange(db.Connection); 
     //MySqlLinqConnectChange(); 

     customer.Address1 = "Original change" + DateTime.UtcNow.Ticks; 
     db.SubmitChanges(); 
    } 
} 

public static void MySqlAdoChange(DbConnection connection) 
{ 
    connection.Open(); 
    var command = connection.CreateCommand(); 
    command.CommandText = "UPDATE customers SET Address1 = 'Conflicting change" + DateTime.UtcNow.Ticks + "' WHERE Username = 'ian2'"; 
    command.ExecuteNonQuery(); 
} 

public static void MySqlLinqConnectChange() 
{ 
    using (MySqlDataContext db = new MySqlDataContext()) 
    { 
     Customer customer = db.Customers.First(c => c.Username.Equals("ian2")); 
     customer.Address1 = "Conflicting change" + DateTime.UtcNow.Ticks; 
     db.SubmitChanges(); 
    } 
} 

Was doppelt seltsam ist, dass die in der Datenbank gespeichert Wert wechselt zwischen den beiden! Ich musste DateTime-Ticks an das Ende anhängen, um die Eindeutigkeit zu gewährleisten, ansonsten wurde mein Update optimiert und nur aktualisiert, um der Wert zu werden, der gerade nicht aktiv war.

Kann jemand dieses Verhalten erklären? Warum kann ich keine ChangeConflictException erzeugen?

Antwort

1

Zunächst ist zu beachten, dass in Ihrem Beispiel-Code, Sie Phone Feld in MySqlTest Funktion aktualisieren, aber Address1 Feld in MySqlAdoChange Funktion, so dass es nicht zu einem Konflikt sein.

Am wahrscheinlichsten, selbst wenn Sie dies korrigieren, haben Sie sowieso keinen Update-Konflikt. Wenn Sie sich Ihren Klassenquellcode Customer ansehen, unter Phone Eigenschaft, werden Sie (am wahrscheinlichsten) sehen, dass es mit Spaltenattribut mit UpdateCheck = UpdateCheck.Never verziert ist (das ist der Standard: sehen Sie hier https://www.devart.com/linqconnect/docs/MemberMapping.html). Daher prüft LinqConnect standardmäßig nicht auf Aktualisierungskonflikte für Ihre Felder, es sei denn, Sie teilen ihm mit, welche Felder überprüft werden sollen, indem Sie sie mit UpdateCheck = UpdateCheck.Always oder UpdateCheck.WhenChanged dekorieren. Natürlich sollten Sie Quellcode nicht direkt ändern, sondern diese Eigenschaft im Modell-Designer ändern.

+0

Sie haben natürlich Recht über das Telefon vs Adresse. Ursprünglich habe ich das Telefonfeld getestet (was eigentlich ein Textfeld ist, aber offensichtlich nicht), dann entschied ich mich, Address zu verwenden, um Dinge zu "vereinfachen" und die SO-Frage nicht korrekt zu aktualisieren. Ich werde mir das Attribut ansehen, das Sie vorschlagen, danke für die Info. Ich habe eine andere Kopfgeldfrage [http://stackoverflow.com/questions/36586779/devart-changeconflictexception-but-values-still-written-to-database?lq=1], die Sie interessieren könnten, diese ist nur eine Teilmenge des größeren Problems. – Ian

+0

Sie waren zweimal genau richtig, meine Variablen waren _all_ (Sperr-ID-PKs), dekoriert mit dem Attribut 'UpdateCheck = UpdateCheck.Never'. Und wenn Sie es entfernen, wird wie erwartet eine Ausnahme generiert. Vielen Dank, das löst die Hälfte meines Problems. Aber es macht jetzt mein anderes 'ChangeConflictException' Problem noch rätselhafter. – Ian