![]() |
AW: TIBCQuery funktionsweise ?
Zitat:
Vereinfacht macht das Framework in etwa folgendes: Abfrage: SELECT <fieldlist> FROM tablename WHERE condition1; Update: try UPDATE tablename SET field1 = value, field2 = value .... WHERE condition2; COMMIT; except ROLLBACK; raise end; Der Knackpunkt ist hier folgender: condition1 liefert normalerweise eine ganze Reihe von Zeilen zurück. Für das UPDATE muss condition2 aber so formuliert sein, das damit exakt eine Zeile in der Tabelle identifiziert wird, nämlich die, die der Benutzer gerade editiert hat. Die einzig generelle Methode, das zu machen (und gleichzeitig die am wenigsten effiziente) ist es, einfach für alle nicht-LOB Felder in der WHERE-Klausel eine Bedingung der Art feld = orginalwert anzugeben. Damit findet der Server den zu ändernden Record nur, wenn er noch nicht von einem anderen Benutzer geändert wurde. Wenn der Record nicht gefunden wird gibt der Server zurück, dass 0 Records geändert wurden, der Client erzeugt daraufhin eine Exception, und (bei automatischen Transaktion-Handling) die Transaktion wird zurückgerollt. Wenn 2 Clients also parallel den gleichen Datensatz bearbeiten gewinnt der, der zuerst das COMMIT ausführt. Erst dann wird der vom UPDATE-Statement erzeugte Datensatz aus der Transaktion der Session in die Datenbank geschrieben. Wie parallele Transaktionen sich auswirken hängt maßgeblich davon ab, wie die WHERE-Klausel des UPDATE-Statements aufgebaut wird. Im Prinzip kann man da z. B. nur den primary key des Datensatzes verwenden. Da sich der aber nie ändert würde man damit aber Kollisionen zwischen Transaktionen nicht erkennen, dann würde das zweite COMMIT eventuell Änderungen des ersten überschreiben. Wenn man das vermeiden will und trotzdem effiziente UPDATEs haben will erfordert das mehr Arbeit, z. B. eine Versionnummer in einem Feld der Tabelle, die nach jedem Update automatisch von einem Trigger hochgezählt wird. Dann kann man die Kombination primary key + Versionsnummer verwenden, um den Datensatz auszuwählen und hat trotzdem eine effiziente Kollisionsdetektion. Nachteil: man muss die Versionsnummer nach dem Update in der clientseitigen Version aktualisieren. All das in diesem Absatz kannst Du im Prinzip vergessen, wenn Du mit data-bound controls und einem der mit Delphi gelieferten data access frameworks arbeitest, da hat man einfach nicht genug Kontrolle über die Details. |
AW: TIBCQuery funktionsweise ?
Hallo,
Zitat:
Wir reden hier von Interbase/Firebird. Da spielt die MGA schon eine größere Rolle (Multi-Generationen-Architektur). |
AW: TIBCQuery funktionsweise ?
Zitat:
|
AW: TIBCQuery funktionsweise ?
Hallo,
ah, OK. Siehe mein Post auf der ersten Seite. Zusammenfassung: Firebird bekommt mit, dass nach dem Starten einer Transaktion ein anderer Nutzer den Datensatz geändert hat, und verhindert das Commit. Gerade, um Datenverlust zu vermeiden, in dem Fall die Daten dessen, der zuerst gespeichert (commited) hat. |
AW: TIBCQuery funktionsweise ?
Zitat:
Der Einspruch wurde abgewiesen, allerdings mit der Maßgabe, das es von der Interpretation des Wortes "parallel" abhängt, was denn da relevant ist. Redet man von zeitlich verschachtelten Transaktionen, (A führt ein Update aus, B tut das gleiche für den gleichen Datensatz bevor A committed ist) ist der Einwand richtig. Diese Art der Kollision kann der Server detektieren und abweisen. Mir ging es aber mehr um Transaktionen, die zwar den gleichen Datensatz verändern, aber zeitlich soweit getrennt sind, das A bereits committed ist wenn B ausgeführt wird. Das ist ein wesentlich praxisnäheres Scenario. In diesem Scenario kann der Server die Kollision nicht detektieren, da bei Ausführen des Updates von B keine offene Transaktion für den gleichen Datensatz mehr existiert. Selbst wenn er feststellt, dass er mehr als eine Version des Datensatzes in "Generationen" hat, die noch nicht mit der Master-Version der Tabelle gemerged wurden, kann er deswegen das Update nicht abweisen, dann könnte man ja einen Datensatz nicht wieder editieren, bevor dieser Abgleich durchgeführt wurde. Das wäre ein nicht akzeptables Verhalten aus der Sicht des Benutzers. Nein, der Server kann das Kollisionsproblem nur teilweise lösen, wirklich lösen kann es nur der Programmierer bzw. DB designer, in dem er sich des Problems bewusst ist und entsprechende Vorkehrungen trifft, mit denen ein Client sicherstellen kann, das er einen Datensatz nur verändert, wenn er noch in dem Zustand ist, in dem er gelesen wurde. So, vielleicht kann ich jetzt wieder einschlafen... |
AW: TIBCQuery funktionsweise ?
Guten Morgen ;)
Zitat:
Ja, in diesem Fall kann das nur der Programmierer lösen. Gute Nacht ;) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:16 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz