SqlConcurrencyException Problem

30/07/2008 - 09:03 von Maik Schütz | Report spam
Einen schönen guten Tag!

Ich benutze gerade das VS 2008 mit C# und den SQL Server 2005. Ich habe ein
Fenster, indem ich mir Daten vom Server hole und in einem DataGridView
anzeigen lasse. Fürs Erstellen der Commands benutze ich einen
SqlCommandBuilder und das Speichern führe ich dann folgendermaßen durch:

*********
dataadapter.Update(ds, "dt_Liste");
*********

Da dass Programm nun von mehreren Benutzern genutzt werden soll, bekomme
ich, wenn zwei Benutzer den gleichen Datensatz geàndert haben eine
SqlConcurrency Exception. Wie ich diesen Fehler abfangen kann, habe ich
schon herausbekommen, aber wie kann man es realisieren, dass wenn z.B. ein
bereits geànderter Datensatz nochmal von jemand anderes geàndert werden
soll, eine Abfrage erscheint in der steht, ob die Änderungen überschrieben
werden sollen oder die Daten nur aktualisiert werden sollen? Dazu habe ich
zwar schon ein Beispiel auf ner MSDN Seite gesehen, aber die benutzen
typisierte DataSets usw. und habe aber alles selber per Code erstellt.

Könnt ihr mir vielleicht ein weiterhelfen, da ich momentan irgendwie aufm
Schlauch stehe?! Oder habt ihr ne ganz andere Vorgehensweise?`

Gruß
Maik S.
 

Lesen sie die antworten

#1 Peter Götz
30/07/2008 - 10:03 | Warnen spam
Hallo Maik,

Ich benutze gerade das VS 2008 mit C# und den
SQL Server 2005. Ich habe ein Fenster, indem
ich mir Daten vom Server hole und in einem
DataGridView anzeigen lasse. Fürs Erstellen
der Commands benutze ich einen
SqlCommandBuilder und das Speichern führe
ich dann folgendermaßen durch:

*********
dataadapter.Update(ds, "dt_Liste");
*********

Da dass Programm nun von mehreren Benutzern
genutzt werden soll, bekomme ich, wenn zwei
Benutzer den gleichen Datensatz geàndert haben
eine SqlConcurrency Exception. Wie ich diesen
Fehler abfangen kann, habe ich schon
herausbekommen, aber wie kann man es realisieren,
dass wenn z.B. ein bereits geànderter Datensatz
nochmal von jemand anderes geàndert werden
soll, eine Abfrage erscheint in der steht, ob die
Änderungen überschrieben werden sollen oder
die Daten nur aktualisiert werden sollen?



Du schreibst doch schon selbst, dass eine Exception
ausgelöst wird, wenn versucht wird einen geànderten
Datensatz zu speichern, den in der Zwischenzeit
schon ein anderer Benutzer geàndert hat.
Genau auf diese Exception musst Du reagieren.
Du kannst in diesem Fall den Benutzer in einem
Dialogfenster fragen, ob er seinen geànderten
Datensatz trotzdem speichern, also die Änderung
des anderen Benutzers überschreiben will, oder
ob der bei ihm selbst vorhandene Datensatz mit
den Änderungen des anderen Benutzers aktualisiert
werden soll.

Die ConcurrencyException wird ausgelöst, weil Dein
UpdateCommand eine über alle Felder des Daten-
satzes reichende Where-Klausel enthàlt und deshalb
bei Deinem DataAdapter.Update der Datensatz in
seiner bisherigen Form nicht mehr gefunden wird.
Ein Command etwa in der Art:

Select ID, FeldA, FeldB From Tabelle
Where (ID = Wert) and (FeldA = Wert) And (FeldX = Wert)

Das Feld ID ist das Primàrschlüsselfeld, eines oder
beide der übrigen Felder hat ein anderer Benutzer
geàndert.

Möchte der Benutzer diesen DS nun aber doch
speichern, musst Du die Where-Klausel für Deinen
zu speichernden Datensatz àndern. In den meisten
Fàllen wird das so aussehen, dass man in die
Where-Klausel des UpdateCommands dann nur
noch ein ID-Feld (Primàrschlüssel) einbezieht.

Select ID, FeldA, FeldB From Tabelle
Where ID = Wert

Mit einer solchen Where-Klausel wird ein anschliessend
ausgeführter Update-Command gelingen, wenn der
Datensatz noch vorhanden und nur in einem oder mehreren
anderen Feldern geàndert worden ist.

Dazu habe ich zwar schon ein Beispiel auf ner MSDN
Seite gesehen, aber die benutzen typisierte DataSets
usw. und habe aber alles selber per Code erstellt.



Ob Deine lokalen Daten in einem DataSet oder wo auch
sonst liegen, hat mit Deiner ConcurrencyException erst
mal gar nichts zu tun.

Könnt ihr mir vielleicht ein weiterhelfen, da ich momentan
irgendwie aufm Schlauch stehe?! Oder habt ihr ne ganz
andere Vorgehensweise?`



Du wàrst sicher gut beraten, Dir erst mal einige
Grundlagen zu SQL und zu Commands anzulesen.
Da Du offenbar einen CommandBuilder benutzt, solltest
Du Dir die OH zu

CommandBuilder.ConflictOption

genauer ansehen. Mit dieser Eigenschaft bestimmst Du,
auf welche Weise der CommandBuilder die Where-
Klausel für Deine Update- und Delete- Commands
erstellt. Bei

CompareAllSearchableValues
geht die Where-Klausel über alle Felder.
Änderungen durch andere Bentuzer an
irgendeinem der Felder lösen eine
ConcurrencyException aus.

CompareRowVersion
Sofern es im Datensatz ein TimeStamp-Feld
gibt, wird dieses in die Where-Klausel ein-
bezogen. Dies führt zu einer Concurrency-
Exception, wenn der eigene (lokale) TimeStamp-
Wert nicht mehr mit dem in der DB enthaltenen
übereinstimmt.

OverwriteChanges
Hierbei werden, sofern vorhanden, nur
Primàrschlüsselfelder in die Where-Klausel einbezogen.
Änderungen an den übrigen Felder führen zu keiner
ConcurrencyException. Ist kein Primàrschlüsselfeld
vorhanden, werden alle Spalten, nach denen gesucht
werden kann in die Where-Klausel einbezogen (s.OH).
Es empfiehlt sich, immer ein Primàrschlüssel in seinen
Datensàtzen zu haben.

Ich setze mal voraus, Deine Datensàtze haben ein
Primàrschlüsselfeld, dann musst Du bei Deinem Commmand-
Builder die Eigenschaft 'ConfliktOption' auf OverwriteChanges
einstellen, um mit dem nàchsten Update einen zwischenzeitlich
von einem anderen Benutzer geànderten DS zu überschreiben.

Ich würde Dir für den Anfang jedoch dringend empfehlen,
erst mal ohne Commandbuilder und DataAdapter und
stattdessen mit ganz einfachen Commands mit entspr.
CommandText zu arbeiten, um erst mal zu lernen, wie
solche Commands überhaupt arbeiten. Auch hinter einem
DataAdapter verbergen sich letztlich nur mehr oder
weniger simple Commands.

Zum Einlesen der Daten also ein

CommandExecuteReader
oder evtl. nur
CommandExecuteScalar

und zum Bearbeiten von Datensàtzen

CommandExecuteNonQuery
mit einem entspr. SQL-Commandtext
(Insert ..., Update ... , Delete... )

Gruß aus St.Georgen
Peter Götz
www.gssg.de (mit VB-Tipps u. Beispielprogrammen)

Ähnliche fragen