Re: Probleme beim umdenken zu ado.net

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance

From: Peter Fleischer (peter.fleischer_nospam__at_gmx.de)
Date: 02/21/05


Date: Mon, 21 Feb 2005 09:52:24 +0100

Sam Jost wrote:
...
> Warten bis der gesperrte Satz wieder frei ist - ich sperre Sätze nur
> wenn sichergestellt ist dass er ohne Benutzeraktion in kurzer Zeit
> wieder freigegeben wird. Normalerweise passiert das innerhalb von
> Sekundenbruchteilen, und so lange kann das nächste Programm locker
> warten.

Sam,
innerhalb eines Datenbankzugriffes wird der Datensatz ja für den parallelen
zugriff gesperrt. Wo siehst du da Probleme?

> Wenn ein Benutzer einen Satz ändern will wird dieser nicht
> gesperrt sondern wie beim Dataset sich gemerkt was vorher drin stand.
> Erst wenn der Benutzer 'speichern' drückt wurde der Satz bei mir
> früher gesperrt, neu geladen,

Dieses erneute Lesen kannst du dir beim DataSet sparen bzw. nach Bedarf
ausführen, da in der DataTable die Originalwerte (=Datenbankinhalt beim
Lesen) gespeichert werden. Diese Orginalwerte werden auch zur Erkennung der
Konkurenzsituation herangezogen.

> verglichen ob jemand anders ihn
> geändert hat, dann verändert und gespeichert - wieder eine Aktion von
> Sekundenbruchteilen in der der Satz gesperrt war.

Das bedeutet, dass auch in dem von dir beschriebenen Szenario eine
Konkurrenzsituation entstehen kann, wenn die geänderten Daten zwischen Lesen
und Rückschreiben von einer anderen Anwendung geändert werden. Das musst du
abfangen, wenn du es im Client und nicht im Server ausführst.

> Wenn ein Satz länger als sagen wir mal 3s gesperrt war war es ein
> Programmfehler/-absturz der auch als solcher protokolliert und
> möglichst berichtigt wurde.

Lass das besser den Datenbankserver machen. Da gibt es keinen
Client-Absturz.

> Damit gab es bei mir nur Sperren die 'vollautomatisch' ohne mögliche
> Benutzerinteraktion garantiert innerhalb von Sekundenbruchteilen
> wieder freigegeben wurden.

Das macht der Datenbankserver für dich für die Zeit des Schreibens.

...
> Das hab ich vielleicht nicht klar formuliert: Ein überschreiben von
> veränderten Daten ist in meinen Augen ein Datenverlust und damit auch
> ein Scheitern (sogar ein besonders schlimmes da mit Pech keiner das
> so schnell merkt das Daten verloren gegangen sind).

So allgemein ist das falsch. Es gibt Anwendungen, wo der letzte Zustand
einzutragen ist und damit der letzte gewinnt. Nimm beispielsweise die
Erfassung von Gesprächsnotizen. In ein Feld, welchen einen Verweis auf die
letzte Gesprächsnotiz enthält, ist der letzte Verweis einzutragen, egal, was
da parallel passiert.

...
>> Transaktion zurückrollen, den betreffenden Datensatz mit den
>> zwischenzeitlich von anderen Benutzer(n) geänderten Inhalten neu
>> einlesen und dann die Änderung noch mal probieren, kannst Du per
>> Programm, ohne den Benutzer zu fragen, doch machen.
>
> Ja, und genau das ist es ja was mir wie gesagt so umständlich
> vorkommt.

Aber in deinem oben skizzierten Szenario ist es doch genau so.

> Ich hab einige solche Automaten, und bei jedem einzubauen
> dass er die Aktion bei Konflikt mehrfach ausführt kommt mir im
> Vergleich zu einer Sperre für Sekundenbruchteile eben so umständlich
> vor.

Dann lass es doch vom Server machen.

...
> 'Wer zuletzt schreibt hat gewonnen' wär für mich das schlimmste
> überhaupt. Ein Beispiel ist dass allseits geliebte Bankkonto mit
> Saldo wo Bewegungen runtergehen: ich würde für sowas einen neuen
> Datensatz anlegen 'Kurt hat 40,- abgehoben', dann das Konto laden und
> den Saldo um 40,- reduzieren. Wenn ich dabei die Änderung des letzten
> einfach überfahre weils zufällig gleichzeitig war stimmt mein Saldo
> nicht mehr, ich hab definitiven Datenverlust: für mein Programm eine
> totale Katastrophe!

Genau das machen die Banken nicht. Sie schreiben am Tag nur die Bewegungen
in eine separate Datei. Nachts läuft dann ein Batch-Job, der die Stände
konsolidiert. Wenn du am Tag eine Auskunft haben willst, dann bekommst
entweder nur den Stand am Morgen oder eine Summe des Standes am Morgen und
der Bewegungsdaten des Tages.

...
> Das TStamp höher zu setzen ist auch eine interessante Idee für eine
> Sperre, werd ich mal drüber nachdenken. Setzt natürlich voraus das
> niemand mit dem Rechnerdatum rumspielt bzw ich mir irgendwie das
> eindeutige vom Server holen kann (denn es ist leider gang und gäbe
> dass für andere Programme das Datum des Rechners umgestellt wird, zB
> um Dinge schon mit nächsten Monat oder im letzten Jahr/Quartal zu
> datieren - das ist ausserhalb meines Programmes, hat mich schon oft
> geärgert, habe ich aber keinen Einfluss drauf und muss es hinnehmen)

Den Timestamp setzt der Datenbank-Server. Da hast du keinen Einfluss. Du
kannst ihn auslesen und mit einer Zeitspanne vergleichen.

>> Es ist also schon auch bei verbindungsloser Arbeitsweise möglich ein
>> sauberes Sperrverhalten zu realisieren. Die Clients (Programm) müssen
>> natürlich alle diese 5-Minuten-Regel kennen und sich auch daran
>> halten.
>
> Klar, ich kann beliebige logische Sperren erfinden, und die
> timestamp-geschichte mit vordatieren ist auf jeden Fall eine
> interessante Idee (vorausgesetzt ich kriege das Serverdatum raus,
> aber das sollte machbar sein).

Es wird nicht vordatiert, sondern der im Datensatz eingetragene Timestamp
mit der aktuellen Serverzeit verglichen und nur diese Differenz ausgewertet.
Das kann man alles im SQL-String machen.

> Ich brauch auch beileibe keine
> physikalische Sperre, eine logische reicht völlig. mich wundert nur
> dass dieses IMHO sinnvolle Feature scheinbar weg ist und wie das dann
> gedacht ist - solche Aktionen wie bei Buchungssystemen sind doch
> eigentlich was ganz alltägliches für Datenbanken, oder nicht?

Jede Lösung ist eben anders und hängt von den Vorgaben zu der zu
realisierenden Organisation ab, weshalb es da keine universelle
vorgeschriebene Lösung gibt.

Peter



Relevant Pages