Laden...

Parallelitätsverletzung Exception abfangen und verarbeiten

Erstellt von caoimhin vor 6 Jahren Letzter Beitrag vor 6 Jahren 1.891 Views
C
caoimhin Themenstarter:in
34 Beiträge seit 2010
vor 6 Jahren
Parallelitätsverletzung Exception abfangen und verarbeiten

verwendetes Datenbanksystem: <Firebird>

Hallo,

ich habe eine Anwendung, welche auf mehreren Arbeitsstationen läuft.
Hin und wieder kommt es dann, wenn auch sehr, sehr, selten zu einer Parallelitätsverletzung.

Was dies bedeutet ist mir durchaus bewusst. Ich würde dies jedoch nun gerne beim Speichern von Daten berücksichtigen/richtig verarbeiten.

Wenn ich es richtig verstanden habe (korrigiert mich wenn ich falsch liege) wird beim Update von Datensätzen geprüft ob die ursprünglich geladenen Daten mit denen in der DB übereinstimmen oder in der Zwischenzeit geändert wurden.

Die Funktion kann man abschalten, davon wird allerdings größtenteils abgeraten.

Jetzt habe ich mir überlegt, was wäre, wenn ich den/die Datensatz/Datensätze bei der Exception überprüfe und anpasse?

Man klickt auf speichern, Exception kommt, dann hole ich mir den Datensatz aus der Datenbank per frischem SQL ab, vergleiche die Werte. Gibt es Differenzen zwischen der Version in der DB und den ursprünglich geladenen Daten, werden diese Werte korrigiert.

Das Problem an dem ich nun hänge ist, dass wenn ich die DataRow per Code anpasse, sich zwar der Wert in selbiger an den der DB anpasst, der DataRowVersion.Original Wert allerdings immer noch der ursprünglich geladene ist, welcher dann zu der Fehlermeldung führt.

Ist es möglich, diesem Feld wieder den Wert Original zuzuweisen?

Alternativ könnte ich natürlich auch auf die optimistische Nebenläufigkeit(wie oben beschrieben wird davon abgeraten) verzichten und jeden Datensatz auf Veränderung prüfen, dies würde allerdings zu lasten der Performance gehen und den Speichervorgang ziemlich langatmig machen.

Vielleicht hat ja jemand einen Wink in die richtige Richtung?

Beste Grüße

caoimhin

Das hoffen wir alle

16.835 Beiträge seit 2008
vor 6 Jahren

Sowas sollte über die Anwendungslogik abgedeckt werden.
Stichworte: Optimistic Concurrency bzw. Sperrverfahren

C
caoimhin Themenstarter:in
34 Beiträge seit 2010
vor 6 Jahren

Sperren von Datensätzen finde ich eher nicht so zielführend und durchaus nervig.

Was spricht denn gegen die von mir vorgeschlagene Vorgehensweise?
Ich versuche ja gerade eben eine Anwendungslogik für genau diesen Fall zu entwickeln.
Die Frage ist nur : Geht es so?

Das hoffen wir alle

16.835 Beiträge seit 2008
vor 6 Jahren

Das eine ist ja das technische, das andere das logische.
Klar kann man das Updaten einfach automatisieren, was aber natürlich immer logische Risiken mit sich bringt; ob das in Deinem Prozess überhaupt erlaubt sein darf.
Ich kenne genug Systeme, bei denen genau das niemals erlaubt werden würde, sondern der Benutzer dann aktiv eingreifen muss.

Technisch gesehen kann man alles mit "Ja" beantworten.
Geht nicht gibt's nicht; alles eine Frage des Aufwandes und der Logik.

R
74 Beiträge seit 2006
vor 6 Jahren

Das Problem an dem ich nun hänge ist, dass wenn ich die DataRow per Code anpasse, sich zwar der Wert in selbiger an den der DB anpasst, der DataRowVersion.Original Wert allerdings immer noch der ursprünglich geladene ist, welcher dann zu der Fehlermeldung führt.

DataTable.Load mit PreserveChanges

https://msdn.microsoft.com/de-de/library/system.data.loadoption(v=vs.110).aspx

kann das Problem lösen. Der DataReader für die Load-Methode ist das
Ergebnis einer Abfrage die genau nur den Datensatz mit der gewünschten
ID holt. Das funktioniert aber alles nur dann so schön, wenn diese ID auch
als Primary-Key im DataTable definiert ist !

Im Ergebnis befinden sich danach die Werte aus Datenbank im DataRowVersion.Original-Wert.

Es gibt 3 Optionen
https://msdn.microsoft.com/de-de/library/system.data.conflictoption(v=vs.110).aspx

wobei CompareAllSearchableValues tatsächlich nur "SearchableValues" einbezieht und das
schließt alle Spalten die als "IsLong" markiert sind in den
Metadaten aus !

Das Problem lässt sich nur durch Verzicht auf DbCommandBuilder und DbAdapter vermeiden,
so dass dann auch "binary blob"- oder varchar-Spalten verglichen werden können.

Nur dann kann für jede Zeile ein individuelles Update erfolgen und ermöglicht
werden, dass 2 Arbeitsplätze den gleichen Datensatz aktualisieren können
wenn jeweils unterschiedliche Felder verändert wurden.

Jede andere Konfliktlösung muss entweder vom Anwender bestätigt oder
durch vorher festzulegende Regeln definiert werden.