PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [postgresql] wurden daten geändert?



Alex_K
14-09-2004, 16:55
ich arbeite zur zeit an einer datenbankanwendung (postgresql mittels libpqxx), die natürlich auch mehrere benutzer zur gleichen zeit benutzen können sollen.

nun hab ich ein problem mit der syncronisation der daten:
benutzer A und B arbeiten zur gleichen zeit in der gleichen DB. die daten werden beim start des programmes von der DB geholt, und lokal zwischengespeichert.
wenn nun benutzer B z.b. einen datensatz einfügt (oder löscht) soll das benutzer A natürlich auch mitbekommen.
zur zeit ist es so gelöst dass bei aktionen, bei denen es wichtig ist aktuelle daten zu haben, einfach alle daten neu von der DB geladen werden. das belastet natürlich die DB, und macht das programm langsamer.

gibt es eine möglichkeit von der DB zu erfahren wann die letzten änderungen vorgenommen wurden? somit könnte ich die daten nur neu laden wenn sich auch wirklich was geändert hat.
oder gibt es vielleicht überhaupt eine andere "referenzlösung" wie so ein problem behandelt werden soll?

Hans-Georg Normann
14-09-2004, 21:39
Hmm, bei FireBird kann man das per Exception (Before Update, Before Insert) lösen. Du erstellst eine Datenbakinterne Funktion, welche dir ein Feld des Tabellensatzes mit dem aktuellen Datum / Zeitwert füllt. Wann immer du einen Datensatz hinzufügst oder änderst, wird diese Funktion automatisch aufgerufen.

Ich kenn jetzt nicht Postgressql, aber ich denke, dass das da auch geht.

Hans

Christoph
15-09-2004, 08:03
@hans-georg:

Du meinst einen Trigger, der die Äanderungshistorie schreibt. Das geht in PostgreSQL, eventuell sogar generisch für alle Tabellen mittels Vererbung (das müsste man mal checken).

@alex:

Eine Änderungshistorie ist aber wohl nicht das was Du möchtest, sondern Du willst immer aktuelle Daten haben. Zu diesem Zweck würde ich das Konzept "Alle Daten beim Programmstart laden" überdenken, zumal dieses Konzept zu inkonsistenten Daten bei Änderungen führen kann.

Warum lädst Du die Daten nicht einfach erst in dem Moment, wenn drauf zugegriffen wird. Zugriffskonflikte lässt Du die Datenbank selber lösen (TRANSACTION ISOLATION LEVEL SERIALIZABLE), wobei zu beachten ist, dass in PostgreSQL Transaktionen explizit mit "begin" getsartet werden, nicht implizit wie bei Oracle (und im SQL2-Standard vorgeschrieben).

Dein derzeitige Lösung ist im Prinizip "lokale Kopie der Datenbank anlegen beim Programmstart". Dies führt zum Problem verteilter Datenbanken => nicht trivial.

Alex_K
15-09-2004, 13:49
@ christoph

ich glaube ich hab das problem schlecht beschrieben.
es werden nicht alle daten beim laden des programmes von der DB geladen, und erst wieder beim beenden zurück gespielt.
am besten beschreib ich es mal mit einem vereinfachten problem einer kundenverwaltung:

das programm soll kunden verwalten (namen, anschrift, kontaktinformationen, ...). das interface ist so aufgebaut dass man in einer tabelle alle kunden mit dernen wichtigsten daten (z.b. kundennummer, name) sieht. dazu lade ich erstmal die informationen die zu dieser übersicht benötigt werden aus der DB (das sind die daten die mit der aussage "beim start des programmes" gemeint habe).
wenn die details eines kunden bearbeitet werden sollen, werden diese nun für den einen kunden in einer transaktion aus der DB geholt, und nach dem bearbeiten wieder gespeichert.

bei einer lösung mittels einer transaktion sehe ich folgendes problem, bitte korrigier mich wenn ich eine einfachere lösung übersehen habe:

um die daten in dem kunden-übersichtsfeld (in dem an die wichtigsten daten zu allen kunden sieht) konsistent zu halten müsste ich eine transaktion bei ersten aufruf (beim ersten anzeigen) starten, und diese erst dann wieder beenden wenn das übersichtsfeld nicht mehr benötigt wird, oder nach jedem commit die daten in diesem feld neu laden.
wird z.b. jedes mal wenn ein kunde bearbeitet wird ein commit gemacht, müsste ich die daten auch genau so oft neu laden wie bei der anderen methode die ich zur zeit verwende.
wenn ich sie nun aber nach bestimmten aktionen nicht commite, und einfach mit dieser transaktion weiter arbeite, dann wird die gefahr dass diese transaktion mit einer anderen möglicherweise nicht serialisierbar ist, und deshalb abgebrochen wird, immer größer je länger ich arbeite. in diesem fall wären dann alle bis zu diesem zeitpunkt durchgeführten änderungen verloren.

Christoph
15-09-2004, 18:37
Ich würde die Daten beim Start des Bearbeiten neu lesen. Wenn die reine Anzeige unbedingt immer aktuell sein muss und du jede Änderung sofort anziegen willst, dann kannst Du es ja mal mit dem Messaging (LISTN und NOTIFY heissen die Befehle glaube ich) in PostgreSQL versuchen; das ist aber Postgres-spezifisch.