Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Exklusiver DB-Zugriff bei gleichzeitig DB-Komponenten (https://www.delphipraxis.net/177263-exklusiver-db-zugriff-bei-gleichzeitig-db-komponenten.html)

Der schöne Günther 28. Okt 2013 17:08

Datenbank: Advantage • Version: 11.10 • Zugriff über: Lokal

Exklusiver DB-Zugriff bei gleichzeitig DB-Komponenten
 
Datenbanken unter Delphi sind für mich immer noch Neuland. Die "Data Aware Components" sind ein Riesenspaß. Ohne großen Aufwand kann man den Benutzer gleich toll Daten anzeigen und eventuell sogar direkt bearbeiten lassen.

Ich möchte allerdings auch ein paar Dinge mit der Datenbank anstellen, die exklusiven Zugriff brauchen: Zu dieser Zeit darf keiner lesen oder schreiben. Klassisches Beispiel: Backup machen oder wiederherstellen.


Mein Problem: Wie kann ich herausfinden, wer eigentlich gerade alles auf mein
Delphi-Quellcode:
TDataSet
zugreift? Ein
Delphi-Quellcode:
TDBGrid
hängt an einem
Delphi-Quellcode:
TDataSource
welches irgendein
Delphi-Quellcode:
TDataSet
belauscht. Die sind mir im Weg, die muss ich vorübergehend abklemmen für meinen exklusiven Zugriff. Nur wie?

Bernhard Geyer 28. Okt 2013 18:55

AW: Exklusiver DB-Zugriff bei gleichzeitig DB-Komponenten
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1233500)
Zu dieser Zeit darf keiner lesen oder schreiben. Klassisches Beispiel: Backup machen oder wiederherstellen.

Schlechtes Beispiel. Alle DBMS-Systeme können Backups erstellen ohne das exklusiver Zugriff besteht. Wenn Sie das nicht können sind sie kein DBMS.

Zitat:

Zitat von Der schöne Günther (Beitrag 1233500)
Mein Problem: Wie kann ich herausfinden, wer eigentlich gerade alles auf mein
Delphi-Quellcode:
TDataSet
zugreift? Ein
Delphi-Quellcode:
TDBGrid
hängt an einem
Delphi-Quellcode:
TDataSource
welches irgendein
Delphi-Quellcode:
TDataSet
belauscht. Die sind mir im Weg, die muss ich vorübergehend abklemmen für meinen exklusiven Zugriff. Nur wie?

Gar nicht. Das können die DB-Zugriffskomponenten von Delphi (und auch von anderen Frameworks) nicht. Dieser exklusiver Zugriff würde auch den eigentlichen Prinzipien von DBMS widersprechen. Was du machen kannst ist eine sogenannte Transaktion starten. Damit kannst du erreichen das mehrerer Aktion die zusammengehören entweder vollständig erfolgreich sind oder vollständig wieder zurück genommen werden.

Was willst du eigentlich genau machen?

Der schöne Günther 28. Okt 2013 20:21

AW: Exklusiver DB-Zugriff bei gleichzeitig DB-Komponenten
 
Ich habe ein lokales Datengrab. Bei laufendem und ordnungsgemäß arbeitendem Programm werden immer mehr Daten (Messungen, Logs, ...) "hinten" angehangen. *
Ich verwende die Sybase Advantage Local DB direkt mit ihren funky Delphi-Komponenten.

Ich möchte beispielsweise verhindern, dass die lokale DB über eine bestimmte Größe wächst und die "ältesten" Datensätze löschen. Für diesen "Pack"-Vorgang brauche ich exklusiven Zugriff. Genauso wenn ich den Datenbank-Inhalt gegen einen anderen austauschen will. Kein alltäglicher Betrieb, nur für "Wartungsarbeiten". Geht nunmal nicht anders. :roteyes:

Es funktioniert auch alles bestens. Wenn nun irgendein blöder
Delphi-Quellcode:
TDBGrid
die ganze Zeit auf meine DB starrt kriege ich die ja allerdings nie kurz exklusiv geöffnet. Nun
  1. Mache ich die ganzen Wartungsarbeiten (die exklusiven Zugriff benötigen) nur zu Programmstart und -ende.
  2. Merke ich mir alle DB-"Observer" um sie nach Belieben aus- und danach wieder einklinken zu können
  3. Es gibt noch etwas besseres


* Es ist eine Sybase Advantage Local DB. Neue Datensätze werden immer hinten angehangen, Datensätze nur zum Löschen markiert und erst beim "Packen" entfernt. Meine fünfseitige Selbstfindung zu dieser DB findet sich auch hier.


PS: Stimmt, Backup geht auch ohne Gefummel. Wiederherstellen aber sicher nicht :-p

Uwe Raabe 28. Okt 2013 21:16

AW: Exklusiver DB-Zugriff bei gleichzeitig DB-Komponenten
 
Ich kann jetzt nicht direkt zu dem Advantage-Server etwas sagen, aber in den meisten Fällen gibt es eine zentrale Stelle, bei der die aktiven DataSets gesammelt werden. Bei der BDE ist es die TDatabase-Instanz, bei DbExpress die TSQLConnection-Instanz und bei FireDac die TADConnection-Instanz - jeweils mit den Properties DataSetCount und DataSets.

Wenn man diese DataSet-Liste temporär kopiert, deaktiviert und nachher wieder aktiviert, müsste man sowas eigentlich implementieren können. Vorausgesetzt, alles läuft im HauptThread ab.

jobo 28. Okt 2013 21:26

AW: Exklusiver DB-Zugriff bei gleichzeitig DB-Komponenten
 
Ist das eine Multiuserumgebung? Eher nicht..?
Wenn es alles lokal ist und Du selbst (der Anwender) ein Restore veranlasst, ist es nicht total ok, wenn man die DBGrids (deren Connection) ausknipst?
Was würdest Du als Anwender erwarten? Das man ein Restore aufruft und das DBgrid kurz unscharf wird und dann zur Darstellung der aktuellen Daten morphed?

Ein anderes Problem wäre, ein Restore zu fahren und dabei weiterhin (wenigstens) Daten zu sammeln.

Kein RDBMS ist im "Moment" des Restore verfügbar! Das ist auch etwas, was man idR nie haben will. Das Restore betrifft die gesamte DB. Die will ich nur aus einem Backup wiederherstellen, wenn sie sich oder jemand anders sie zerstört, korrumpiert, was weiß ich, hat.

Es gibt eine Technik, die man Partitionierung nennt. Damit werden Daten z.B. nach Timestamp (Jahre, Monate, Geschäftsjahr, Typisierung ..) geclustert, physikalisch separiet / indiziert, .. mglw in Deinem Fall nützlich und verfügbar.

Ansonsten wäre es eine Überlegung wert, dass Du per Datenmodell verschiedene "Töpfe" von Anfang an vorsiehst. Sprich separate Tabellen, für "alles was grad reinkommt", "für Export", "Backup inside", "eingehende Daten für Versuchsaufbau bei Vollmond".
Format immer identisch, vielleicht nicht mal als verschiedene Tabellen, sondern als Spalte/Klasse/Kennung einer einzigen Tabelle (siehe Partitionierung)

Das Verschieben, Export, Restore von Topf zu Topf ist dann einerseits Update auf die Kennungsspalte und im Fall import/export ein insert/delete.

Der schöne Günther 28. Okt 2013 21:35

AW: Exklusiver DB-Zugriff bei gleichzeitig DB-Komponenten
 
Richtig, lokale Datenbank, nur mein Prozess greift drauf zu.

Gute Idee mit der Unterteilung :thumb:
Auf lange Sicht werde ich das vielleicht auch machen.

Und natürlich, das Wiederherstellen eines Backups ist natürlich ein absoluter Sonderfall. Und wenn ich dabei nicht gleichzeitig noch die Daten sehe ist das auch absolut selbstverständlich. Mein "Problem" ist ein anderes: Ich wollte weiterhin unkompliziert Oberflächen zusammenklicken und eventuell neue Connection, Table und Query-Objekte verwenden. In meinem Anwendungscode für Backup/Restore möchte ich die aber nicht wieder haarklein zusammensuchen müssen um sie einmal abzuschalten damit ich in Ruhe an der Datenbank schrauben kann.

Dass es in der BDE und dbExpress eine "zentrale Sammelstelle" gibt macht weiterhin Hoffnung. Ich schaue mir die anderen ADS-Delphikomponenten mal an, vielleicht ist es ja ganz offensichtlich...

sx2008 28. Okt 2013 23:36

AW: Exklusiver DB-Zugriff bei gleichzeitig DB-Komponenten
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1233535)
In meinem Anwendungscode für Backup/Restore möchte ich die aber nicht wieder haarklein zusammensuchen müssen um sie einmal abzuschalten damit ich in Ruhe an der Datenbank schrauben kann

Ich würde das Problem im Sourcecode der Hauptanwendung komplett ignorieren.
Stattdessen gibt es ein Wartungstool, dass die Datenbank exklusiv öffnet und die Datenbank packt.

jobo 29. Okt 2013 07:09

AW: Exklusiver DB-Zugriff bei gleichzeitig DB-Komponenten
 
Ich verstehe das Problem mit den Komponenten nicht richtig.
Wenn Du eine Single User Anwendung mit lokaler DB hast, ist doch alles sehr übersichtlich.
Du hast in einer "normalen" Anwendung idR ein Connection Object. Da hängen alle DB Komponenten dran. Wenn die Connection getrennt wird, sind alle DB Kompos "abgeschnitten".
Am einfachsten wäre nun m.E. aus der gleichen Anwendung das Backup aufzurufen, weil gerade hier die Kontrolle über das Disconnect der DB Kompos am größten ist.
Sprich die Anwendung läuft in 2 Modi: Wartung und Betrieb. Der User wählt das über entsprechende Menupunkt und Du bist nahezu 100 Pro sicher, was geht.
Ich weiß nicht, ob Deine DB per SQL gesichert und restored werden kann, das wäre ggF. noch einfacher als externe Befehle aufzurufen. Ansonsten müsstest Du in Deinem Programm vielleicht noch sicherstellen, dass es nur einmal gestartet werden kann (per Mutex oder mittlerweile irgendwie auch anders). So oder so sollte man per Abfrage von Systemviews sehen können, ob/wieviele Connections geöffnet sind oder sogar noch Datensatz/Objektsperren vorliegen.
Das würde ein ordentliches Backup (nicht Filecopy) natürlich sowieso tun und Probleme zurückmelden.

Bernhard Geyer 29. Okt 2013 07:31

AW: Exklusiver DB-Zugriff bei gleichzeitig DB-Komponenten
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1233535)
Richtig, lokale Datenbank, nur mein Prozess greift drauf zu.

Auch wenn oben Lokal steht ist das nicht klar. Dann kann man es sich (wie schon jobo angemerkt hat) einfacher machen.

hstreicher 29. Okt 2013 09:32

AW: Exklusiver DB-Zugriff bei gleichzeitig DB-Komponenten
 
nur zur Erinnerung , es geht hier um die Fortsetzung von

http://www.delphipraxis.net/176409-l...auche-ich.html

Er verwendet den DB Server im Uralt DBase Modus

Der schöne Günther 29. Okt 2013 11:38

AW: Exklusiver DB-Zugriff bei gleichzeitig DB-Komponenten
 
Zitat:

Zitat von jobo (Beitrag 1233572)
Wenn Du eine Single User Anwendung mit lokaler DB hast, ist doch alles sehr übersichtlich. Du hast in einer "normalen" Anwendung idR ein Connection Object. Da hängen alle DB Komponenten dran. Wenn die Connection getrennt wird, sind alle DB Kompos "abgeschnitten".

Ganz genau!

Wahrscheinlich verleitet mich Delphi gerade zum Schlampen, denn genau das habe ich nicht mehr beibehalten. Connection und Query-Objekt auf Form/Frame werfen und das mit Grids, Charts und sonstwas direkt schön visualisieren. So habe ich locker schonmal zwei, drei Readonly-Verbindungen auf meine Datenbank. Verbindungen, die fest mit meiner Oberfläche verdrahtet sind.

Die Anwendungslogik dahinter weiß von diesen Verbindungen nichts. Und will sie jetzt finden um sie auszuknipsen.

Ziemlich blöd gelöst, oder? Irgendwie ging mir schon einer dabei ab, auf dem Formular-Designer schon den DB-Inhalt sehen zu können. Aber ich komme immer mehr zum Schluss, dass man es lieber "ordentlich" und alles über ein Verbindungsobjekt laufen lassen sollte...

Uwe Raabe 29. Okt 2013 12:02

AW: Exklusiver DB-Zugriff bei gleichzeitig DB-Komponenten
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1233617)
Irgendwie ging mir schon einer dabei ab, auf dem Formular-Designer schon den DB-Inhalt sehen zu können. Aber ich komme immer mehr zum Schluss, dass man es lieber "ordentlich" und alles über ein Verbindungsobjekt laufen lassen sollte...

Das schließt sich ja nicht aus. Du kannst das eine (einzige?) Verbindungsobjekt ja in ein Datenmodul packen, das du dann bei den jeweiligen Forms in die uses-clause schreibst. Wenn das Datenmodul dann in der IDE geöffnet ist, kannst du den DataSets dieses Verbindungsobjekt zuweisen.

Der schöne Günther 29. Okt 2013 12:30

AW: Exklusiver DB-Zugriff bei gleichzeitig DB-Komponenten
 
Fast! Ganz reichen meine Fähigkeiten leider nicht aus: Der Formular-Designer findet problemlos eine Verbindungs-Komponente die man auf ein ganz anderes Formular geworfen hat. Aber leider nur über die globale "Form2"-Variable.

Oder bezeichnet "Datenmodul" etwas, das ich nicht kenne?

DeddyH 29. Okt 2013 12:34

AW: Exklusiver DB-Zugriff bei gleichzeitig DB-Komponenten
 
http://docwiki.embarcadero.com/Libra...es.TDataModule

Der schöne Günther 29. Okt 2013 13:05

AW: Exklusiver DB-Zugriff bei gleichzeitig DB-Komponenten
 
Gut, dass ich nochmal nachgefragt habe :-)
Das sehe ich zum ersten mal. Und es sieht sehr, sehr vielversprechend aus.

Zitat:

Wenn Sie (...) vorhaben, Gruppen von Datenbank- und Systemobjekten wiederzuverwenden, oder wenn Sie die Teile Ihrer Anwendung isolieren wollen, die die Verbindung zu Datenbanken einrichten und Business-Regeln implementieren, stellen Datenmodule ein praktisches Werkzeug für die Organisation dar.
Nach Frames die zweite große tolle Entdeckung im Stil von "Hätte ich das doch nur früher mal entdeckt"...

Eine Sache noch: Um das Verkoppeln von bsp. einem TDBGrid mit etwas von einem Datenmodul (oder anderen Formular oder Frame) komme ich aber anscheinend um diese blöde globale Variable nicht drum herum, oder? Papa sagt, globale Variablen seien böse.

Medium 29. Okt 2013 13:12

AW: Exklusiver DB-Zugriff bei gleichzeitig DB-Komponenten
 
Über irgend etwas musst du den Container ja referenzieren, und die globale Form-/DM-Variable ist ja schon von der IDE als "The correct Delphi way" vorgegeben. Ich habe mich aus praktischen Gründen damit abgefunden diese als letzte Vertreter ihrer Art zu tolerieren. (Ausser bei Formularen, die ich nur dynamisch instanziere.) Andere Lösungen (so es sie denn gibt) würden sehr wahrscheinlich auch nicht so einfach von der IDE unterstützt, so dass der Nutzen des Ganzen wieder fraglich wäre.

Uwe Raabe 29. Okt 2013 13:25

AW: Exklusiver DB-Zugriff bei gleichzeitig DB-Komponenten
 
Ich würde das hier auch rein pragmatisch sehen. Wenn du in der IDE die Live-Verbindung zur Datenbank willst, kommst du um diesen Weg wohl nicht herum. Denk auch daran, das Datenmodul in die automatische Form-Erzeugung mit aufzunehmen (außer: siehe unten).

Es ist auch nicht wirklich die globale Variable, die Delphi da verwendet, sondern vielmehr die Instanz dieses Datenmoduls mit dem entsprechenden Namen ("Wozu haben Komponenten Namen?"). Beim Laden der Forms löst Delphi die Referenz auf das Datenmodul auf, indem es die Namen der Instanzen überprüft. Das Verbindungsobjekt sucht es dann über FindComponent innerhalb dieser Instanz.

Du kannst also problemlos zur Runtime selbst eine passende Instanz des Datenmoduls (vor den Forms) erstellen (den Namen bekommt es aus der DFM), das dann auch von den verschiedenen Forms verwendet wird. Die globale Variable kannst du dann auch entfernen. Es darf aber weiterhin nur eine Instanz dieses Datenmoduls geben - was aber ja auch der Sinn des ganzen ist.

Der schöne Günther 29. Okt 2013 13:32

AW: Exklusiver DB-Zugriff bei gleichzeitig DB-Komponenten
 
Richtig, die Anwendung kompilierte zwar, konnte aber nicht starten, da in der
Delphi-Quellcode:
Application.CreateForms
-Reihenfolge das Datenmodul nach dem Formular kam.

Dann bedanke ich mich auf jeden Fall noch ganz anständig, denn insgesamt ist das, was ich die ganze Zeit wollte. 8-)

joachimd 29. Okt 2013 13:44

AW: Exklusiver DB-Zugriff bei gleichzeitig DB-Komponenten
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1233644)
Es darf aber weiterhin nur eine Instanz dieses Datenmoduls geben - was aber ja auch der Sinn des ganzen ist.

Nicht zwingend ... ich lege oft komplette Business Objekte in ein Datenmodul und erzeuge das dann pro Anzeigeformular entsprechend. Das trennt dann die DB-Verbindung in mehrere, voneinaner unabhängige auf. Allerdings muss man dann peinlich darauf achten, wenn es um solche Tasks mit Exklusiv-Zugriff geht.

Uwe Raabe 29. Okt 2013 15:00

AW: Exklusiver DB-Zugriff bei gleichzeitig DB-Komponenten
 
Zitat:

Zitat von joachimd (Beitrag 1233652)
Zitat:

Zitat von Uwe Raabe (Beitrag 1233644)
Es darf aber weiterhin nur eine Instanz dieses Datenmoduls geben - was aber ja auch der Sinn des ganzen ist.

Nicht zwingend ...

In diesem Fall schon. Es ging darum, eine zentrale Stelle zu schaffen, über die man an die aktuell aktiven DataSets kommen kann. Meine Aussage sollte natürlich nicht bedeutet, daß es generell immer nur eine Instanz dieses Datenmoduls respektive nur eine Verbindung zur Datenbank geben darf.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:18 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