Autor Beitrag
AndreM
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 122

Win2k, WinXP, Suse 10
D7 Ent
BeitragVerfasst: Di 06.04.04 18:52 
Hallo Community,

ich habe mal wieder ein kleines Datenbankproblem. Und zwar bin ich derzeit dabei eine kleine Anwendung zu schreiben, die auf eine Internbase-Datenbank zugreift. Da die Software im Netz genutzt wird, kann es also vorkommen, dass mehrere Clients gleichzeitig mit der Datenbank verbunden sind und somit auch gleichzeitig Daten ändern können.
Jetzt möchte ich, dass Änderungen die vom einen Client vorgenommen worden sind automatisch bei allen anderen Clients aktualisiert werden. Mein Problem ist nämlich das der eine Client die Änderungen des anderen Clients erst mitbekommen, wenn der Client komplett geschlossen wurde und neu gestartet worden ist. Auch ein erneutest ausführen eines Selects bringt keine Lösung, da die Daten scheinbar erst aktualisiert werden, wenn eine neue Verbindung zur Datenbank aufgebaut wird.
Hoffe mal ich konnte mein Problem einigermaßen schildern, so dass ihr verstanden habt was ich möchte. :D

Ich hab eventuell überlegt, ob sich das irgendwie über einen Broadcast realisieren läßt, aber damit habe ich leider noch überhaupt keine Erfahrungen gemacht.
hansa
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3079
Erhaltene Danke: 9



BeitragVerfasst: Di 06.04.04 19:06 
Das Zauberwort heißt : "Commit"

_________________
Gruß
Hansa
AndreM Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 122

Win2k, WinXP, Suse 10
D7 Ent
BeitragVerfasst: Di 06.04.04 19:19 
Ich führe nach jeder Änderung ein Commit aus, aber trotzdem wird das bei den anderen Clients nicht angezeigt.
atarigold
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 84

WIN XP, Linux 2.4
D7, Delphi 2006 Prof
BeitragVerfasst: Di 06.04.04 19:31 
Die Antwort von Hansa triffts auf den Punkt.

Änderungen werden in Datenbanken mit Transaktionskontrolle erst dann physikalisch ausgeführt, wenn anschließend ein Commit gesendet wird. (Beim Beenden einer DB-Verbindung macht Delphi dieses automatisch).

Wenn du mit den Clients über Abfragen auf die Daten zugreifst muss natürlich auch (anschließend !) die Abfrage neu ausgeführt werden, um die Änderung sichtbar zu machen.
AndreM Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 122

Win2k, WinXP, Suse 10
D7 Ent
BeitragVerfasst: Mi 07.04.04 18:12 
Jup, das ganze ist mir schon klar. Nur leider funktioniert es nicht.

Also die Daten werden ganz sicher mit einem Commit vom Client in die Datenbank geschrieben, denn wenn ich einen neuen Datensatz anlegen und den Client mit welchem der Datensatz erzeugt wurde nicht schließe und anschließend einen neuen Client öffne, dann befindet sich der neue Datensatz auch wie es sich gehört im neuen Client wieder.
Wenn ich jedoch in einem Client schauen, der zum Zeitpunkt des Anlegens bereits geöffnet war, muß ich die Verbindung zur Datenbank zunächst abbauen und diese dann danach neu aufbauen, damit der Datensatz erscheint.
neojones
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1206
Erhaltene Danke: 1



BeitragVerfasst: Mi 07.04.04 18:30 
CachedUpdates = True? Könnte ne Ursache sein.

@atarigold: Nicht zwangsläufig wird beim Trennen einer DB-Connection ein Commit gemacht. Dieses Commit löst nämlich nicht Delphi bzw. das Programm aus, sondern der Datenbanksocket. Und wenn der so eingestellt ist, dass er beim Trennen einen Rollback macht, haste nen Problem ;-)

_________________
Ha! Es compiliert! Wir können ausliefern!
AndreM Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 122

Win2k, WinXP, Suse 10
D7 Ent
BeitragVerfasst: Mi 07.04.04 18:44 
neojones hat folgendes geschrieben:
CachedUpdates = True? Könnte ne Ursache sein.

Hatte ich auch schon dran gedacht, aber das steht auf FALSE.
Was mir jetzt noch aufgefallen ist, ist dass der jeweils andere Client die Änderungen mitbekommt, sobald er selber eine Datensatzänderung durchführt. Soll heißen, ich lösche in Client A einen Datensatz gehen dann in Client B und lese die Datensätze neu ein, dann ist der eben gelöschte Datensatz noch vorhanden. Wähle ich in Client B jetzt jedoch einen anderen Datensatz aus und führe eine Änderung durch, so das ein Commit ausgeführt wird, verschwindet auch automatisch der von Client A gelöschte Datensatz. Wenn ich jetzt wieder in Client A gehe, dann ist die Änderung von Client B noch nicht zu sehen. Sobald in Client A jetzt jedoch ein Commit ausgeführt wird, wird auch die Änderung von Client B sichtbar.
Und bevor gefragt wird, ja ich habe vorher die Select-Abfrage neu ausgeführt. Aber keine Chance, der Client bekommt die Änderungen erst mit, wenn er selber etwas in der Datenbank geändert hat.
Irgendwie hab ich das Gefühl das ich da an irgendeiner Stelle nen Bock habe! :D
hansa
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3079
Erhaltene Danke: 9



BeitragVerfasst: Mi 07.04.04 20:09 
Wird überhaupt die gleiche Transaktion commited ?

_________________
Gruß
Hansa
AndreM Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 122

Win2k, WinXP, Suse 10
D7 Ent
BeitragVerfasst: Do 08.04.04 06:25 
hansa hat folgendes geschrieben:
Wird überhaupt die gleiche Transaktion commited ?

Ja, aber dürfte doch eigentlich egal sein, da der eine Client ja nicht weiß, welche Transaktion im anderen Client comitted wird. Aber ich nutze lediglich eine Transaktion, da ich der Datenbank ja nicht mehr als eine Transaktion zuweisen kann, kann ich dies ganz sicher bestätigen.
neojones
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1206
Erhaltene Danke: 1



BeitragVerfasst: Do 08.04.04 10:43 
Mit welchen Kompos machst Du Select und Update?

_________________
Ha! Es compiliert! Wir können ausliefern!
AndreM Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 122

Win2k, WinXP, Suse 10
D7 Ent
BeitragVerfasst: Do 08.04.04 12:36 
neojones hat folgendes geschrieben:
Mit welchen Kompos machst Du Select und Update?

Mit dem IBDataSet bzw. dem IBQuery die bei Delphi 5 bereits dabei sind.
neojones
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1206
Erhaltene Danke: 1



BeitragVerfasst: Do 08.04.04 13:08 
Da muss ich jetzt passen und übergebe mich an den nächsten ;-)

Sorry, aber mit denen hab ich noch nie was gemacht.

_________________
Ha! Es compiliert! Wir können ausliefern!
CenBells
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1547

Win 7
Delphi XE5 Pro
BeitragVerfasst: Do 08.04.04 15:54 
hallo,

also, du musst deine Transaktion, auf dem client der die änderungen laden soll auch commiten.
Prinzipiell würde ich dir getriggerte events empfehlen. Damit mache ich das bei meinen Projekten ganz erfolgreich.
Ich benutze auch IBQuerys. Zeigst du die daten in den clients in einem DBGrid an? Dann ist das relativ ungeeignetes Anwendungs-Design, was CS-Architektur angeht. Verwendest du in deinen Transactionen Commit Retaining?
Also, wie gesagt, Events und Trigger benutzen und dann mit der IBEvents componente die entsprechenden events abfangen und neuladen auslösen. Hierbei bietet sich natürlich an, einen geeigneten Entwurf zu verwenden, so daß immer nur der wirklich geänderte Record neu geladen wird.

Gruß
Ken

_________________
Eine Klasse beschreibt die Struktur und das Verhalten einer Menge gleichartiger Objekte.
Lemmy
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 792
Erhaltene Danke: 49

Windows 7 / 10; CentOS 7; LinuxMint
Delphi 7-XE10.1, VS 2015
BeitragVerfasst: Do 08.04.04 16:52 
Hi Ken,

CenBells hat folgendes geschrieben:

also, du musst deine Transaktion, auf dem client der die änderungen laden soll auch commiten.
Prinzipiell würde ich dir getriggerte events empfehlen. Damit mache ich das bei meinen Projekten ganz erfolgreich.


Welche Version von IB/FB verwendest Du und auf welchen Plattformen?? Immer wenn es um Events geht habe ich das Gefühl, dass jeder nur Probleme damit hat...

Grüße
Lemmy
CenBells
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1547

Win 7
Delphi XE5 Pro
BeitragVerfasst: Do 08.04.04 17:03 
Hallo,

ich verwende Events seit IB6.01 Server bei einem Kunden Linux, Clients Windows 100 MBit Netzwerk.
Bei den anderen Kunden Server auf Windows und Clients ebenfalls.
Firebird in der Version 1.5 und alles funktioniert einwandfrei. Klar, es waren an manchen Stellen ein paar Anpassungen notwendig, die waren aber nicht weiter wild.

Die Kunden sind begeistert und der für notfälle eingebaute Refresh button wird so gut wie nicht benötigt.

Gruß
Ken

_________________
Eine Klasse beschreibt die Struktur und das Verhalten einer Menge gleichartiger Objekte.
AndreM Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 122

Win2k, WinXP, Suse 10
D7 Ent
BeitragVerfasst: Fr 09.04.04 15:28 
Hallo,

erstmal besten Dank für eure Tipps. Jetzt weiß ich zumindest schon einmal, dass es einen Weg gibt mein Problem zu lösen! :D
Aber leider bin ich auf dem Gebiet von Datenbanken noch ein kleiner Newbie und würde mich daher sehr über ein wenig hilfestellung freuen. Wie genau kann ich in der Datenbank über einen Trigger ein Event auslösen?

Also ich habe jetzt erstmal einen neuen Trigger in der Datenbank ausgelöst, welcher der Tabelle BENUTZER zugeordnet ist und den Namen BENUTZER_EVENT hat. Der Typ des Triggers ist AFTER INSERT. Der Inhalt ist folgender:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
AS
begin
  POST_EVENT 'update_benutzer';
end


Jetzt habe ich auf das entsprechende Form ein IBEvent gelegt, die entsprechende Datenbank zugewiesen und REGISTERED auf TRUE gestellt. Im Ereignis OnEventAlarm habe ich die Select-Anweisung die zum aktualisieren genommen wird hinzugefügt.
Wenn ich jetzt jedoch das entsprechende Form aufrufe erhalte ich immer die Fehlermeldung "error reading data from connection".

Das was ich oben geschrieben habe, war wahrscheinlich totaler Müll, so dass es überhaupt nicht klappen kann, aber wie gesagt, ich bin Newbie! :D
CenBells
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1547

Win 7
Delphi XE5 Pro
BeitragVerfasst: Sa 10.04.04 12:38 
AndreM hat folgendes geschrieben:
sprechende Form ein IBEvent gelegt, die entsprechende Datenbank zugewiesen und REGISTERED auf TRUE gestellt. Im Ereignis OnEventAlarm habe ich die Select-Anweisung die zum aktualisieren genommen wird hinzugefügt.
Wenn ich jetzt jedoch das entsprechende Form aufrufe erhalte ich immer die Fehlermeldung "error reading data from connection"....


Hallo,

wo hast du die select anweisung hinzugefügt? Also, wenn das event in deiner anwendung ankommt, muss du das IBQuery, welches zum anzeigen der daten verwendet wird aktualisieren.... (close; open; )

Gruß
Ken

_________________
Eine Klasse beschreibt die Struktur und das Verhalten einer Menge gleichartiger Objekte.
AndreM Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 122

Win2k, WinXP, Suse 10
D7 Ent
BeitragVerfasst: Sa 10.04.04 13:36 
Also, ich habe bisher folgendes gemacht.
Den Trigger in der Datenbank angelegt, mit obigen Code.
Auf dem Form Benutzer habe ich ein IBEvent hinzugefügt. Bei diesem habe ich in das erste Event update_benutzer geschrieben und Registered auf TRUE gesetzt. In das Ereignis OnEventAlert habe ich folgenden Code geschrieben.
ausblenden Delphi-Quelltext
1:
2:
DataSet_Benutzer.Close;
  DataSet_Benutzer.Open;

Dieses DataSet beinhaltet die Select-Anweisung um alle Benutzer aus der Datenbank auszulesen.
Wenn ich jetzt mein Projekt starte und das Entsprechende Form bzw. das Chield erzeuge (Anwendung ist eine MDI-Anwendung), dann erhalte ich seitdem ich das Event hinzugefügt habe diese Fehlermeldung.
user defined image
Das komische daran ist, dass diese Meldung manchmal bereits beim erzeugen des ersten Chields erscheint und manchmal erst, nachdem ich noch ein zweites Chield erzeugt habe. Klingt nen wenig Kompeliziert, hoffe aber mal, dass ihr mich trotzdem versteht! :D

Sobald ich das Event wieder auf Registered = FALSE stelle, verschwindet auch die Fehlermeldung wieder. Also liegt es definitv an der verwendung von dem IBEvent.
AndreM Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 122

Win2k, WinXP, Suse 10
D7 Ent
BeitragVerfasst: Mo 12.04.04 14:42 
Hallo,

ich habe das Problem gefunden, weshalb mein Programm abstürzt. Das Problem ist die verwendung von Events auf einem MDI-Chield. Wenn ich das Event auf das MainForm lege funktioniert das ganze ganz wunderbar. Nur habe ich dann ja das Problem, dass ich nicht mehr auf die DataSet die im MDI-Chield verwendet werden, zugreifen kann, da ich die Chields ja nicht mehr vom Programm aus ansteuern kann.
Hoffe mal ihr versteht was ich meine! :D
Gibt es da eventuell auch noch eine Lösung für???

-->Edit: OK, hat sich erledigt. Hatte nen Denkfehler drin! :D