www.mikrocontroller.net

Forum: PC-Programmierung [MySQL] Mutex, Locks, große Verständnisprobleme


Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Morgen,

ich hab immer noch große Verständnisprobleme mit MySQL und 
Nebenläufigkeit.

Abstrahiert ist mein Problem folgendes:

Angenommen ich hab eine Tabelle, die ganz simpel einfach so aussieht:

id (primary, int), value1 (int), value2 (int)

und ich hab User, die über ein Java Servlet Einträge in der DB 
hinterlassen können.

Hierbei soll es - vereinfacht - mehrere Regeln geben:
- value1 < value2 (das ist immer gegeben und muss nicht gesondern 
berücksichtigt werden)
- Es dürfen keine Überschneidungen von Intervallen [val1;val2] in der 
Datenbank existieren. Beispiel:

Wenn zwei User folgendes Eintragen:
val1 = 10, val2 = 100, dann ist das quasi ein Interval [10;100], dann 
darf kein User z.B. [5;50] eintragen, aber er dürfte [5;9] eintragen.

Soweit ist das hoffentlich klar. In der Realität handelt es sich um 
konvexe Polygone, die sich nicht überschneiden dürfen, aber ich denke, 
für die Erklärung ist das verständlich. Wichtig ist - glaub ich 
zumindest - dass es von MySQL keine Möglichkeit gibt, das beim Insert zu 
überprüfen.

Das Problem hierbei ist jetzt, dass ich im Grunde erstmal nachschauen 
muss, ob das Intervall, das eingetragen werden soll, in der Datenbank 
existiert und wenn nicht, dann wird es eingetragen. Die Servlets können 
aber im Grunde parallel und sogar auf verschiedenen Rechnern 
gleichzeitig ausgeführt werden und da gibts dann die bekannten Probleme, 
wofür man normalerweise Mutex verwendet.

Es gibt hierzu mehrere Ideen, wie man das Problem lösen kann:
- Die Servlets mit einem Mutex locken - ist aber Gift für die 
Skalierbarkeit und funktioniert nicht in z.B. einer Cloud.
- Die Tabelle mit einem MySQL-Lock locken, da besteht aber das Problem, 
dass ich zu 99% unnötig die Tabelle locke und andere User, die 
Intervalle eintragen wollen, die nicht im Konflikt sind, unnötig 
abbremsen würde.

Hat da jemand eine Ahnung, wie sowas funktionieren könnte?

Wäre dankbar für Hilfe ... Das Problem verwirrt mich jetzt schon seit 
ein paar Wochen und da muss es doch eine einfache und effiziente Lösung 
geben ...

Grüße,
Markus

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du könntest einen Trigger auf Insert/Updates setzen und die 
entsprechende Aktion ggf. zurückweisen.

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit Triggern hab ich bisher noch nichts gemacht, aber auf den ersten 
Blick sehen die Möglichkeiten interessant aus.

Was ich bisher gelesen habe, müsste ich aber dann im Trigger die 
Überprüfung der Intervalls, bzw in der echten Anwendung eines Polygons 
machen, was wahrscheinlich nicht möglich ist.

In der echten Applikation ist es so, dass ich zusätzlich zum Polygon 
auch das Umgebende Rechteck gespeichert habe und so schnell mögliche 
Kandidaten finden kann, die man genauer untersuchen muss.

Ich bezweifle, dass es hierfür eine effiziente ähnliche Möglichkeit in 
MySQL-Syntax als Trigger gibt ...

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lock wäre sicherlich das einfachste für eine erste Lösung, wenn es 
Probleme mit der Skalierbarkeit gibt würde ich auch versuchen die 
Überprüfung in einem Trigger zu machen.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist MySQL unverzichtbar? PostgreSQL hat ein exclusion constraint, das 
möglicherweise in der Lage ist, solche inhaltlichen Beziehungen der rows 
untereinander abzubilden.

http://www.postgresql.org/docs/9.0/interactive/sql...

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Schwarz schrieb:
> Genau dafür wurden Transaktionen erfunden.

Es wäre nett, wenn du das etwas ausführlicher erläutern könntest.

Ich nehm Transaktionen her, um zu gewährleisten, dass meine DB 
konsistent bleibt im Fehlerfall, weil ich dann einen Rollback machen 
kann.

Ein Zeilen-Lock, wie bei "SELECT ... FOR UPDATE" oder sowas, trifft hier 
ja nicht zu, weil eine neue Zeile eingefügt wird, die von allen anderen 
Zeilen im Prinzip abhängt. Wüsste also nicht, wie ich da um einen 
Table-Lock herumkommen sollte oder wie das mit Transaktionen gehen soll.

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Schwarz schrieb:
> Lock wäre sicherlich das einfachste für eine erste Lösung, wenn es
> Probleme mit der Skalierbarkeit gibt würde ich auch versuchen die
> Überprüfung in einem Trigger zu machen.

Okay, das ist eine gute Aussage. Dann behalte ich das mal im Hinterkopf 
und versuchs mit Table Locks.


@A.K.
> Ist MySQL unverzichtbar? PostgreSQL hat ein exclusion constraint, das
> möglicherweise in der Lage ist, solche inhaltlichen Beziehungen der rows
> untereinander abzubilden.

Interessant, mit PostgreSQL hab ich noch nichts gemacht. Nein, ich bin 
nicht an MySQL gebunden - es hatte bisher einfach das gemacht was es 
soll.

Ich schau mir die Möglichkeiten von PostgreSQL an und auch wieviel 
Arbeit es wäre, mein bestehendes Projekt umzustellen, für den Fall, 
PostgreSQL kann wirklich das, was ich brauche.

Danke!

Grüße,
Markus

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
NB: PostgreSQL kennt sogar geometrische Daten wie Polygone als Datentyp:
http://www.postgresql.org/docs/9.0/interactive/dat...

Autor: der mechatroniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mit Transaktionen gehts prinzipiell so (nicht MySQL-Syntax):
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

IF NOT EXISTS (SELECT * FROM tabelle WHERE value1 < @value2 OR value2 > @value1)
INSERT tabelle @id, @value1,  @value2
ELSE RAISERROR 'Gips schon...'

ist aber deadlock-verdächtig und läuft evtl. während des Insert auch auf 
einen Table-Lock hinaus...

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> NB: PostgreSQL kennt sogar geometrische Daten wie Polygone als Datentyp:
> http://www.postgresql.org/docs/9.0/interactive/dat...

Sehr interessant! PostgreSQL hat auch Geometrische Funktionen, mit denen 
man direkt testen kann, ob sich z.B. Polygone schneiden.

Dann könnte man wirklich Trigger bauen, die erst die Polygon-Kandidaten 
bestimmen und dann nochmal genau schauen, ob sich da was schneidet.

Danke für die Hinweise!

Grüße,
Markus

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mittlerweile hab ich meine DB nach PostgreSQL migriert und das war ein 
Haufen Arbeit. Scheint keine guten automatischen Tools zu geben, die die 
Constraings für Fremdschlüssel, die Sequenzgeneratoren für 
Primärschlüssel oder die Indizes mitübernehmen. Oder sie kosten was ;)

Dann musste ich feststellen, dass der org.postgres.PGpolygon datentyp 
zwar von datanucleus supported wird, das aber in einem nutzlosen bytea 
in der DB landet und damit nutzlos wird.

Mit PostGIS funktionierts jetzt, aber dann hätte ich auch OpenGIS mit 
mysql verwenden können, was Andreas schon angemerkt hat.

Naja, Hat ein paar Tage gekostet, aber es macht jetzt das, was es soll.

Eine letzte Frage vlt ...

Wenn ich einen On-Insert Trigger baue, muss ich innerhalb des Triggers 
irgendwas locken? Oder werden die Trigger ausschließlich seriell 
ausgeführt?

Grüße,
Markus

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
muahahaha it's alive!!!! ;)
CREATE OR REPLACE FUNCTION dsstand_insert_gispolygon() RETURNS TRIGGER AS 
$body$
  DECLARE
    myrec RECORD;
  BEGIN
    SELECT "ID" INTO myrec FROM "DSSTAND" WHERE Intersects( "GISPOLYGON", NEW."GISPOLYGON") AND "ID" != NEW."ID"  LIMIT 1;
    IF FOUND THEN
      RAISE EXCEPTION 'POLYGON INTERSECTING!';
    ELSE
      RETURN NEW;
    END IF;
  END;
$body$ LANGUAGE plpgsql;

Muss ich da noch Table-Locks reinbauen, oder werden die Trigger 
sequenziell abgearbeitet?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.