Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Firebird deadlock Strategie (https://www.delphipraxis.net/71895-firebird-deadlock-strategie.html)

hanspeter 22. Jun 2006 09:33

Datenbank: Firebird • Version: 1.5.2 • Zugriff über: IbObjects

Firebird deadlock Strategie
 
Hallo,

In einem Projekt greifen 2 Anwender gleichzeitig auf eine Liste zu und bearbeiten diese.
Einer von beiden erhält einen deadlook.
Dieser läßt sich zur Zeit nur durch Neustart des Servers beseitigen.

Beim Lesen der Liste zur Bearbeitung gehe ich folgendermaßen vor:

Starttransaction
Lese alle Daten und speichere diese intern
Commit

Nach einer beliebig langen Bearbeitungszeit dann
StartTransaction
Schreibe alle signifikanten Daten zurück
Commit

Warum und wann der deadlook kommt ist mir schon klar.
Ich denke aber über eine Strategie nach, diesen zu behandeln.
(Warum behebt nur ein Serverneustart den deadlook?)

Ich stelle mir vor die Schreiboperation der gesamten Liste in einen try except Block zu stellen.
(Fehler werden weiter unten bereits mit try except abgefangen, den Deadlook könnte ich bis oben
durchreichen.)

Im deadlook Fall sollte es doch reichen, eine Beliebige(???) Leseoperation des Anwenders auszuführen
also
Starttransaction
Lese irgendDaten
Commit
und dann die Schreiboperation zu wiederholen?
Oder muss ich alle Datensätze der betreffenden Liste neu lesen?


Es müssen immer > 1 Datensätze (Größenordnung 5 .. 120) zurückgeschrieben werden.
Ich möchte das so lösen, dass nach einem Deadlook die gesamte Liste neu zurückgeschrieben wird.

Ob eine SP zum Rückschreiben einen Erfolg bringt ist mir im Moment auch nicht ganz klar, da innerhalb der Datenbank ja keine Transactionssteuerung möglich ist.

Stored Procedure:
Lese Datensatz
Update Datensatz

Für einen Denkanstoss dankbar.

Peter

hanspeter 23. Jun 2006 06:44

Re: Firebird deadlock Strategie
 
Mal vorsichtig puschen.
Hat sich noch keiner mit deadlooks geplagt?

Gruß Peter

mquadrat 23. Jun 2006 09:15

Re: Firebird deadlock Strategie
 
Machst du denn ein Rollback der Transaction wenn du einen Deadlock bekommst? Bekommst du nur bei einer der Transactions den Deadlock oder bei allen (deadly embrace)?

Ich würde jeden Datensatz in einer eigenen Transactionen zurückschreiben. Dann kannst du im Try..except Block eine Liste mit allen fehlerhaften Updates führen und dem Benutzer beispielsweise die Zeilen rot markieren, an denen es ein Konflikt gab. So würden wenigstens die geschrieben, die konfliktfrei sind.

Lemmy 23. Jun 2006 09:36

Re: Firebird deadlock Strategie
 
Zitat:

Zitat von mquadrat
Ich würde jeden Datensatz in einer eigenen Transactionen zurückschreiben. Dann kannst du im Try..except Block eine Liste mit allen fehlerhaften Updates führen und dem Benutzer beispielsweise die Zeilen rot markieren, an denen es ein Konflikt gab. So würden wenigstens die geschrieben, die konfliktfrei sind.

mit der Gefahr eine Inkonsistente Datenbank zu erhalten? Dieses System funktioniert nur, wenn die Daten nichts miteinander zu tun haben!

Zitat:

Zitat von hanspeter
Warum und wann der deadlook kommt ist mir schon klar.

Gut für dich... mir ist es nicht klar wann er kommt. Doch eigentlich ist es mir schon klar, ein Deadlock kann nur dann kommen, wenn 2 unterschiedliche Transaktionen zu selben Zeit ein und denselben Datensatz ändern wollen. Was mir nicht klar ist, warum er bei dir kommt, weil du die Transaktion vor dem Schreiben NEU öffnest. Gut, wenn die Datenbank unter "Dauerfeuer" steht und immer neue Daten eingetragen werden, die automatische Änderungen an Tabellen zur Folge haben (Beispiel folgt), kann es durchaus schnell zu Deadlocks kommen:

Beispiel Bestellsystem: Wenn eine Bestellung eingegeben wird, soll neben dem Bestellzettel auch der Warenbestand aktualisiert werden. Wenn mehrere User Bestellungen eintippen kommt es zwangsläufig zu einem Deadlock, wenn man die Warenaktualisierung innerhalb einer StoredProcedure bzw. duch einen Trigger vornimmt.

Als Lösungsmöglichkeit bietet sich an, die Struktur dahingehend umzubauen, dass ein Bestellpool eingerichtet wird. Schlägt die automatische Aktualisierung des Inventars aufgrund eines Deadlocks fehl, wird in dem Pool ein neuer Datensatz angelegt, in dem die Artikelnummer und die Anzahl gespeichert wird. Diese Tabelle wird vom System dann hin und wieder abgearbeitet und in die eigentliche Tabelle umgeschrieben. Das bedeutet aber auch, dass bei einer Verfügbarkeitsprüfung diese Tabelle ebenfalls berücksichtigt werden muss.

Wie gesagt: Mir ist nicht klar, warum es bei Dir unbedingt zu dem Deadlock kommt, außer die beiden ändern dauernd den gleichen Datensatz (vergiss bitte die oben beschriebenen automatismen nicht) und speichern diesen auch gleichzeitig ab.


Grüße
Lemmy

mquadrat 23. Jun 2006 09:44

Re: Firebird deadlock Strategie
 
Zitat:

Zitat von Lemmy
mit der Gefahr eine Inkonsistente Datenbank zu erhalten? Dieses System funktioniert nur, wenn die Daten nichts miteinander zu tun haben!

Richtig, davon bin ich mal bei dem Wort "Liste" ausgegangen.

hanspeter 23. Jun 2006 14:50

Re: Firebird deadlock Strategie
 
Der deadlook ist immer auf "menschliches Versagen" zurückzuführen.
Wobei das Versagen natürlich relativ ist und ich diesen Fall gerne abfangen möchte.

Das Programm läuft im Veranstaltungsbüro einer Sportveranstaltung. Da stehen mehrere vernetzte PC.
Auf einem PC wird die Starterliste einer Prüfung bearbeitet.
Plötzlich klingelt das Handy am anderen Ende des Raums. Irgendeiner geht hin und in der gerade bearbeiteten
Startliste kommt eine Änderung.
Jetzt wird diese schnell an einem anderen Arbeitsplatz geöffnet, ein bischen geändert und geschlossen.
Damit ist der deadlock am 2. Arbeitsplatz vorprogrammiert.

Gibt es eigentlich in FB eine Möglichkeit Tabellen tenmporär zu sperren?

Im deadlock Fall könnte ich dann

Tabelle sperren
Start Transaction
Datensatz lesen und Änderung vergleichen (jeder Satz führt den Timestamp der letzten Änderung mit)
Datensatz speichern

(Das für max 150 Datensätze)

Commit

Die Sperrzeit sollte bei diesem Verfahren unter 1 sec liegen und ist vom Anwender nicht beeinflussbar.

Gruß
hans peter

mquadrat 23. Jun 2006 15:09

Re: Firebird deadlock Strategie
 
Ich würde das so machen, wie bereits beschrieben. Jeden Datensatz einzeln und dann markieren, wo es gehakt hat. Schließlich müssen sich die zwei Mitarbeiter ja dann abstimmen, welche Änderung diejenige ist, die gemacht werden soll.

Abgesehen davon würde ich jede Änderung sofort schreiben. Oder kommt es vor, dass jemand 100 Starter bearbeitet und das dann nicht commiten will?

hanspeter 23. Jun 2006 20:32

Re: Firebird deadlock Strategie
 
Zitat:

Zitat von mquadrat
Abgesehen davon würde ich jede Änderung sofort schreiben. Oder kommt es vor, dass jemand 100 Starter bearbeitet und das dann nicht commiten will?

Das ist nicht wirklich sinnvoll.
Letzendlich ist das auch ein Zeitproblem.
1 Stunde vor Prüfungsbeginn ist Meldeschluss.
Rein formal muss dann keine Startmeldung mehr angenommen werden.
Macht man es doch, dann kommt mein Problem.
Da Zeitdruck besteht, wird das an allen möglichen Rechnern versucht.
Ein Mitarbeiter öffnet die Startliste und stellt dann eine Startreihenfolge her.
Da wird praktisch das gesamte Starterfeld durcheinander gewirbelt.
Teilweise erfolgt auch eine automatische Verlosung der Startreihenfolge oder es muss das Ergebnis einer vorhergehenden Prüfung herangezogen werden.
Auf die Startreihenfolge warten alle anderen Starter.
Nach der Generierung der Folge wird diese über einen Schalter in die Datenbank zurückgeschrieben.
Die Gültigkeit der Liste muss explizit freigegeben werden, da nach der Freigabe sofort die Übertragung in die Pressestelle, das Internet u.s.w. erfolgt.

Gruß Peter


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:32 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz