PostgreSQL Best Practice: Konkurrierender DB-Zugriff mit meherern Programmen?

T

tuxedo

Gast
Hallo zusammen,

bisher hatte ich immer nur eine Anwendung die auf eine DB zugegriffen hat. Da war es noch recht easy, aber nun geht es um folgendes:

Wir haben 3 Anwendungen auf einer Maschine (eine Serveranwendung, eine Konsolenanwendung, sowie eine C++ Anwendung), welche Daten in mehrere Tabellen eines PostgreSQL einfügen und auch bearbeiten.

Das ganze ist ein über mehr als 10 Jahre gewachsenes System und nicht wirklich einfach zu durchschauen. Aktuell haben wir das Problem, dass wenn die Maschine gut ausgelastet ist und es viele Daten zu verarbeiten gilt, die Datenbank sehr oft (rund 160x am Tag, für uns ist das sehr oft) in ein Deadlock läuft:

Process 20066 waits for ShareLock on transaction 199566375; blocked by process 24520.
Process 24520 waits for ShareLock on transaction 199566378; blocked by process 20066.

Postgres schieß dann einen der beiden Prozesse ab, welcher dann ein Rollback fährt und die Geschichte geht in einem neuen Versuch von vorne los.

Alle Aktionen auf der Datenbank laufen innerhalb von Transactions. Meine bisherige Analyse:

Prozess A aktualisiert Datensatz 1
Prozess B aktualisert Datensatz 2
Prozess B aktualisert Datensatz 1
-> B wartet nun bis A seine Transaktion abgeschlossen hat und 1 freigibt
Prozess A aktualisiert 2
-> A wartet nun bis B seine Transaktion abgeschlossen hat und 2 freigibt

Da sich die Reihenfolge der Updates nur schwer festlegen lässt (hängt davon ab was über's Netzwerk für Anfragen eingehen), und es unter Umständen von der C++ Anwendung dutzende Instanzen geben kann (das variiert), lässt sich das nur schwer lösen.

So wie ich das sehe, wird wohl ein größerer Umbau anstehen....

Meine Frage nun:

Wenn man so eine Konstellation hat, wo tatsächlich mehrere Programme auf ein und dieselbe Tabelle einer DB zugreifen und Daten einfügen/ändern müssen: Gibt's da irgendwelche Best-Practice Regeln oder Vorgehensweisen?

* Ein Punkt hab ich bereits gefunden: Aktionen nach Möglichkeit immer in derselben Reihenfolge ausführen.

Mehr hab ich noch nicht gefunden. Onkel Google lässt sich dazu nur schwer befragen, da dies irgendwie schon "etwas spezielles" ist. Und einfach die ganze Tabelle 'locken' wenn jemand was drauf tut könnte die Performance wohl noch weiter in die Knie zwingen.

- Alex
 

FArt

Top Contributor
Klassisches Deadlock, bei dem die DB dann ein dead lock victim aussucht.

Unter welchem Transaktionsisolationslevel arbeitet die DB gerade? Evtl. ist ein anderes für euch besser geeignet.
 
T

tuxedo

Gast
Klassisches Deadlock, bei dem die DB dann ein dead lock victim aussucht.

Unter welchem Transaktionsisolationslevel arbeitet die DB gerade? Evtl. ist ein anderes für euch besser geeignet.

Ich geh mal von "default" aus. Was das bei Postgres ist, müsste ich erst nachschlagen.

- Alex
 

FArt

Top Contributor
Evtl. reicht es ja dann auf "serializable" zu gehen... die Frage kann auch sein, ob den ACID überall nötig ist. Auch andere Möglichkeiten (außerhalb der DB) bzgl. Queueing (asynchron) und Synchronisation kann man in Betracht ziehen.

Kommt aber (wie immer) auf den konkreten Fall an, was die besser Lösung sein wird. Dafür muss man die Anforderungen aller Beteiligten kennen und berücksichtigen, inklusive der nicht funktionalen Anforderungen z.B. bzgl. der Performance bzw. Antwortzeiten.
 
T

tuxedo

Gast
Default ist, soweit ich jetzt gelesen hab, "READ COMMITED". "SERIALIZE" klingt erstmal nach einer passenden Lösung. Allerdings blockiert da eine Transaction nicht wenn eine andere schon läuft, sondern bricht ab und man muss es nochmals versuchen:

http://www.postgresql.org/docs/8.1/static/transaction-iso.html#XACT-SERIALIZABLE hat gesagt.:
However, applications using this level must be prepared to retry transactions due to serialization failures.

Das würde heissen, ich müsste alle Codestellen an denen Transactions verwendet werden durchprüfen, ob die damit zurecht kommen und ggf. anpassen.

Am liebsten wär's mir, es gäbe eine zentrale Anlaufstelle, wo ich außerhalb der DB synchronisieren/queuen könnte. Aber das wäre ein zu großer Umbau des Systems.

Ich denke ich hab mittlerweile die entsprechende Stelle im Programm (auf Java Seite) gefunden die das Problem verursacht. Hab hier mal ein "Explicit Lock" auf die Tabelle gesetzt. Tests laufen gerade ob das die Situation verbessert. Wäre der kleinste EIngriff mit dem geringsten Risiko (außer ggf. Performance einbußen). Mal schauen.

Danke für die Tipps soweit.

Gruß
Alex
 

FArt

Top Contributor
Wenn asynchrones Verhalten möglich ist, es also nur darauf ankommt, dass die Daten sicher in der DB landen, es aber ein wenig dauern kann, dann kann man eine Queue mit JMS realisieren. Die Messages werden auch hier transaktional verarbeitet, somit geht nichts verloren.
 
T

tuxedo

Gast
Es betrifft leider nicht nur Java-Programme, sondern auch C/C++ Programme. Und da ich nicht jede einzelne Stelle die mit der DB arbeiten anfassen will, fällt hier JMS gleich zweimal flach.

Im übrigen haben erste Tests gezeigt: Der "Explicit Lock Mode" funktioniert an dieser Stelle für uns ziemlich zuverlässig.
 

tomier

Aktives Mitglied
Kann jemand einige gute How-Tos dazu empfehlen? Ich stehe vor einem ähnlichen Problem.

Bei mir ist es nur so das ich eine Server-Database habe (h2-servermode) und auf jedem rechner eine h2-embedded, welche ihre Daten abgleichen sollen.

Hat da jemand Erfahrung? Wie kann man diese Zugriffe regeln und bestimmen welcher PC mit der embedded Daten überschreiben darf und welcher nicht?
 
T

tuxedo

Gast
Ist das was du da suchst nicht unter dem Stichwort "Database Replication" zu finden?

Wenn nicht:

und bestimmen welcher PC mit der embedded Daten überschreiben darf und welcher nicht?

Wer überschreibt jetzt wo? Mehr Details bitte. Klingt auch eher nach Rechtemanagement und weniger nach "Zugriff-Synchronisierung/Locking".
 

tomier

Aktives Mitglied
"Ist das was du da suchst nicht unter dem Stichwort "Database Replication" zu finden?
Wenn nicht:
Zitat:
und bestimmen welcher PC mit der embedded Daten überschreiben darf und welcher nicht?
Wer überschreibt jetzt wo? Mehr Details bitte. Klingt auch eher nach Rechtemanagement und weniger nach "Zugriff-Synchronisierung/Locking".

Meine Umwelt sieht so aus:

- Server mit H2-database in server mode
- Büro-Rechner mit H2-database in embedded mode
- Produktionshallen-Rechner mit H2-database in embedded mode

Der Datenbestand soll mit beiden embedded abgeglichen werden.
Z.B. Auf dem Büro-Rechner wird etwas geändert, dass wird lokal in die embedded gespeichert und soll dann in die am Server synchronisiert werden.

Zur Zeit ist es sogar so, wenn ich lokal das Programm ein zweites Mal öffnen will kommt die Meldung "Database locked in use" (Es erlaubt also nur eine einzige Verbindung. ist aber im embedded mode).

Ich weiß auch nicht wie ich einen mehrfachen Zugriff erlaube bzw. kann ich Warteschlangen machen bzw. in die selbe Tabelle von 2 PCs aus gleich reinschreiben (aber unterschiedlicher Datensatz einmal mit ID 1 und der andere PC auf ID2) ??

Zudem weißt du vielleicht wie ich eine kleine Installationmaske mache? Wo einmal der Büro-Modus installiert werden kann oder der Produktionshallenmodus?

Etwas viel aber wenn du paar Tipps oder konkrete Lösungen kennst wäre ich dir dankbar.
 
T

tuxedo

Gast
Schau mal auf der H2 Webseite. Da findest du unterschiedliche Verbindungsparameter. Für gleichzeitigen Zugriff auf eine H2 Datenbank benötigst du AFAIK "Serialize" als Parameter in der JDBC URL.

Das Synchronisieren von deinen Embedded zum Server:

Entweder "zu Fuß" mit Triggern in Verbindung mit passenden Tabellen-Locks (kommt drauf an was du da lles im Detail machst), oder ein passenden Framework für die Replikation benutzen. Da gibt's eigentlich genug Material via Google.

Zudem weißt du vielleicht wie ich eine kleine Installationmaske mache?

Aha. Hat jetzt aber weniger mit einem Datenbankproblem zu tun, oder? --> Anderes Problem -> weitere Frage im passenden Unter-Forum.

Etwas viel aber wenn du paar Tipps oder konkrete Lösungen kennst wäre ich dir dankbar.

Mir scheint du hast dir, ohne viel Vorwissen, ein Schema definiert, von dem du nichtmal weiß ob und wie es funktioniert.
Gibt es einen wichtigen Grund warum du unbedingt einen zentralen DB Server, und nochmal 2 embedded benötigst? Und warum muss jeder direkt mit einer DB (zentral oder eben lokalö) sprechen? Warum nicht einen Server mit einer DB Instanz, und dann die Clients welche via RPC o.ä. mit dem Server sprechen? Wenn es wegen Ausfallsicherheit etc ist: Dann lieber den Server ausfallsicher gestalten als jeden Client mit einer eigenen DB ausstatten und die dann nach einem Fehlerfall wieder in den rückkehrenden, zentralen Server zu synchronisieren.

- Alex
 

tomier

Aktives Mitglied
Danke für die ausführliche Antwort. Das große Problem ist das der Produktionshallen-PC nur per WLAN über einen Hof verbunden ist und das ist eine größere Distanz. Da kann die Verbindung ab und zu mal abreißen. Dieser Rechner muss aber immer seine Daten speichern und funktionieren. Wenn die Daten erst 24 Stunden später zentral verfügbar sind, ist das kein Problem. Eine Kabellösung ist nicht machbar.
 
T

tuxedo

Gast
Mit der Info ergeben sich noch ganz andere Probleme:

Zentraler Server fällt wg. WLAN-Problemen 12h aus. Zu beginn dieser Zeit arbeiten 2 Clients unabhängig voneinander mit anfangs gleichen Datensätzen. Beide Clients haben zueinander keine Synchronisation. Wie verhinderst du, dass beide Clients ein und denselben Datensatz unterschiedlich bearbeiten? Das bekommst du nicht mehr automatisch synchronisiert...

Mein Tipp: WLAN-Richtfunk über den Hof. Bei direkter Sichtverbindung ist das auch noch über einige hundert Meter stabil. Allerdings nur mit guter WLAN-Bridge-Hardware. Hatte gut 2 Jahre lang eine 300m Richtfunkstrecke ohne 100%ige Sichtverbindung mittels 2 Linksys-AccessPoints (WRT54GL) und selbstbau Dosen-Antennen. Lief immer stabil mit etwa 36Mbit (bei 54mbit Hardware). Auch bei Wind und Wetter. Wenn du da keine Selbstbaulösung, sondern etwas professionelleres benutzt, und zudem noch für eine Sichtverbindung zwischen den beiden Gebäuden (Büro? + Produktionshalle) sorgen kannst, seh ich da kein Problem. Hab schon für mehrere Firmen gearbeitet die das so gemacht haben. In Ergänzung dazu:

* Zentraler Server mit der kompletten Business-Logik und einer zentralen DB
* Clients kommunizieren via RPC o.ä. mit dem Server
* Für Schreibzugriff auf die Daten ist eine Verbindung zum zentralen Server Vorraussetzung
* Clients können lokal Daten für den reinen Lese-Zugriff cachen. Ob in einer lokalen embedded DB oder mit einem anderen Cache-Mechanismus ist dir überlassen.
 
T

tomier..

Gast
Vielen Dank für die Tipps.
Dann werde ich mal auf diesem Schema aufsetzen.

Für den RPC ist das ONC RPC/XDR recht gut?

Welche professionelle WLAN-Bridges kannst du empfehlen?
 
T

tuxedo

Gast
Für den RPC ist das ONC RPC/XDR recht gut?

Ich zweifel so langsam daran dass das was wird. Hast du etwas einfach nach "Java + RPC" gegoogelt, bist auf Wikipedia gestoßen und hast nach "Die am weitesten verbreitete Variante ist das ONC RPC ..." aufgehört zu lesen/recherchieren? Ich hoffe nicht.

RPC Techniken gibt's viele. Die bekannteste ist wohl Java RMI. Daneben gibt's noch dutzende andere. Welche für dich am besten ist hängt davon ab, was du damit machen willst. Wenn du allerdings gar keinen Plan hast, schau dir vielleicht erstmal RMI an (oder auch meine Alternative, siehe Signatur).

Welche professionelle WLAN-Bridges kannst du empfehlen?

Wie wär's wenn diejenigen, die das Netzwerk in der Firma betreuen sich darum kümmern? Oder bist du nicht nur für Software, sondern auch für Hardware zuständig?
Ansonsten kann ich aus eigenen Erfahrungen zu Cisco bzw. wenn's billiger sein muss zu Linksys raten (Linksys gehört mittlerweile zu Cisco). Am besten Geräte nehmen die im 5Ghz Band senden. Das 2.4Ghz Band ist schon ziemlich überlaufen. Dann noch wetterfeste Richtfunk-Außenantennen mit der passenden Antennencharakteristik und die passenden Antennenkabel (aber keine 20 meter Kabel und Adapter dazwischen. Das frisst alles Sendeleistung). Und pass auch auf, dass du die 100mW EIRP Sendeleistung nicht überschreitest. Sonst darfst du diese Anlage nicht mehr ohne weiteres betreiben.

Am besten fährst du allerdings wenn sich jemand um die Wlan-Richtfunkbrücke kümmert der sich auskennt und weiß was er da tut. Sonst steht vielleicht bald die Bundesnetzagentur vor der Tür...
 
T

tuxedo

Gast
Ohne die Umgebung in der das Ding aufgestellt werden soll zu kennen kann wohl keiner was dazu sagen. Unter optimalen Bedingungen ist das Teil wohl nicht sooo verkehrt. Aber wie gesagt: Man kann bei Richtfunkverbindungen viel falsch machen.

Wenn du keine Firma kommen lassen willst die dir das einrichtet bleibt dir nur eins: Bestellen, ausprobieren und dazulernen.

- Alex
 

tomier

Aktives Mitglied
Das ist mir klar tuxedo aber ich will es ja lernen ;). Mir ging es nur um das Gerät im Vergleich mit z.B Alvarion BreezeNETb10. Zwei von den Ubiquinto kosten ca. 150 Euro der Alvarion 1700 euro, da muss ein großer Unterschied sein. Die Distanz beträgt ca. 20-30 Meter eine direkte Sichtverbindung wird eingerichtet.
 
T

tuxedo

Gast
Bei 20-30m Distanz kannst du die Fresnelzone bei freier Sicht aller voraussicht nach ignorieren. Musst da also nicht anfangen rumzurechnen wenn du nicht durch einen "schmalen und flachen Tunnel senden willst".

d1 und d2 sind jedoch nicht exakt die halbe Distanz. Da spielt die Ausdehnung r noch mit. Deshalb sind die zwei Linien nicht waagerecht, sondern leicht nach unten gerichtet. Lamda hängt vom verwendeten Frequenzband ab. Aber wie gesagt: Bei der Distanz ist die AUsdehnung r so gering, dass du das vernachlässigen kannst. Hab bei meiner Richtfunktstrecke auch nicht rumgerechnet. Ausreichend freie Sicht, eine gute Richtantenne und stabile WLAN-Hardware sind in der Regel ausreichend. Ggf. hier und bisschen drehen, dort ein bisschen drehen und die Sache passt.

Professionelle Firmen messen dir das Sicher aus und stellen die Anlage ohne viel probieren sofort funktionierend hin. Aber wenn du da selbst Hand anlegst und gewisse Freiheiten in Sachen anbringung hast, dann klappt das i.d.R. auch ohne Taschenrechner. Und 20-30m sind absolut unkritisch. Erst recht bei freier Sicht. Da könntest du wohzl auch zwei normale AccessPoints mit Rundstrahl-Anstenne nehmen. Aber mit Richtfunkantennen bist du da auf jeden Fall auf der sicheren Seite. Hat auch den Vorteil, dass nicht jeder das Signal mitkriegt (Hinter einer Richtfunkantenne verliert sich die Signalstärke für gewöhnlich recht schnell, deshlab auch das Wort RICHTfunk).

Alles in allem hat das aber nichts mehr mit dem Thema Datenbank zu tun. Mehr Hilfe findest du in dedizierten WLAN-/Netzwerk-Foren.

- Alex
 

Ähnliche Java Themen


Oben