MySql Zugriff serialisieren

Thomasio

Erfahrenes Mitglied
Meine Kenntnisse in MySql beschränken sich auf allerunterste Basis, ein einfaches query in PHP für SELECT, UPDATE und INSERT, das wars.

Nun möchte ich gerne Schreib-Zugriffe serialisieren, sprich ich möchte etwa sowas machen:

1) Prüfen ob die Tabelle von jemand Anderem gesperrt ist, wenn ja warten bis frei.
2) Tabelle sperren, so dass nur ich sie ändern oder schreiben kann (Lesezugriff weiterhin erlaubt)
3) Daten lesen
4) Ein paar Prüfungen mit den gelesenen Daten durchführen (solange die Tabelle gesperrt ist bleiben die Daten ja unverändert).
5) UPDATE und/oder INSERT
6) Tabelle freigeben

Ich habe schon ein paarmal versucht Google dazu zu befragen, aber was der ausspuckt ist meistens für meine Anfängerkenntnisse zu hoch, und/oder es stehen ein paar Anmerkungen dabei, die besagen, dass das so nicht sicher ist.

Ich habe mir mit meinen Basiskenntnissen eine sehr umständliche eigene Funktion gebastelt, die ist zwar sicher, aber hat so kleine Haken, wie z.B. dass das ganze PHP-Script sich aufhängt, wenn während "warten bis frei" aus irgendeinem Grunde die Verbindung zum MySql Server unterbrochen wird.

Der langen Rede kurzer Sinn: Hat jemand einen Tip, wie man das lösen kann, oder wo dies für Anfänger verständlich erklärt ist?
 
Zunächst einmal, wo serialisierst du denn den Zugriff? Sprich, wo wird ein Verbindungs- bzw. Result-Objekt serialisiert? Kann es sein, das du zwei verschiedene Begrifflichkeiten (Serialisieren != Locken) durch einander bringst?

Grundsätzlich verwendet man LOCK TABLES.
 
Gut möglich, dass ich das falsche Wort verwende, serialisieren heisst für mich Zugriffe hintereinander statt gleichzeitig, wenn das in korrekter MySql Syntax locken heisst, auch recht.

LOCK TABLES habe ich mir angesehen, scheint auf den ersten Blick auch halbwegs einfach zu sein, aber ich Anfänger sehe da den Wald vor lauter Bäumen nicht.
Es macht scheinbar schon grosse Unterschiede, welche Engine man verwendet, MyIsam, InnoDB, oder was, dann gibt es nocht ein Dutzend verschiedene Arten von Lock, und am Ende steht nirgendwo dabei, was passiert, wenn ein Client LOCK TABLES aufruft und seine Verbindung verliert, bevor er UNLOCK TABLES aufrufen kann, oder in kurz, ich blicke nicht durch.

Vielleicht noch zur weiteren Klärung:
Meine Tabellen verwenden MyIsam.
Die Datenmengen und Anzahl Zugriffe sind so klein, dass ich mir absolut keine Sorgen darum mache, ob die eine oder die andere Methode eine Millisekunde schneller ist, ich Anfänger hätte fürs Erste gerne eine Methode, bei der der Code kurz und übersichtlich und die Funktion narrensicher ist.
Es wäre mir sogar egal, wenn ich die gesamte Datenbank locken müsste, solange sicher gestellt ist, dass alle User in eine Warteschleife kommen und keiner eine Fehlermeldung ala "Access denied" bekommt ist das alles kein Problem.
 
Nunja, das mit dem Client-Abbruch kannst du relativ leicht testen. Du erstellst ein PHP-Script, was sich connected, eine DB wählt und dann einen Test-Lock durchführt. Dann lässt du das Script mit sleep() schlafen, was dann so in etwa das gleiche wäre, wenn das Script ne Menge zu tun hätte. Dann brichst du das Script mit die() einfach ab.

Jetzt öffnest du deinen Browser in zwei Tabs oder arbeitest mit zwei Browsern. Du rufst in beiden Tabs/Instanzen das Script relativ zügig (hängt von deinem sleep() ab) auf und schaust, was passiert. Um das ganze dann aber wenigstens auch nachvollziehen zu können, solltest du evtl an geeigneten Punkten eine Ausgabe über den Zustand der Laufzeit innerhalb des Scripts zu visualisieren.

Aber ich sag das mal so: Wenn MySQL nicht in der Lage wäre, den Lock bei Verbindungsabbruch implizit zu lösen, dürfte es sich nicht RDBMS schimpfen ;-)

Getestet habe ich das allerdings noch nicht. In der englischen Version des Handbuches wird meine Annahme allerdings unter "Rules for Lock Acquisition" bestätigt.

Ich sehe außerdem nur zwei LOCK-Arten: Read und Write. Was das bedeutet, sagen die Begriffe von sich aus.

Vielleicht bringt dir aber little-idiot noch was (nicht falsch verstehen, ist DIE Anlaufstelle für Fragen zu MySQL).
 
Vielen Dank, das hilft mir auf jeden Fall auf den Weg.
"little-idiot" kannte ich noch nicht, habe ich mir direkt in die Favoriten eingetragen.
 
Semi-OT: Und damit dein "serialisieren" auch noch geklärt wird: In der Programmierung läuft grundsätzlich alles seriell ab, so lange man nicht mit Threads oder mehreren Instanzen arbeitet.

(De-)Serialisieren ist ein feststehender Begriff, bei dem es darum geht, beliebige Objekte aus dem Speicher auf ein Medium dauerhaft zu persistieren. Es wird auch für allerlei Tricks missbraucht, aber die ursprüngliche Intention war, beispielsweise eine Session für den nächsten Zugriff auf die Festplatte des Webservers zu schreiben.

Nur damit du den Begriff nicht im falschem Kontext betrachtest. Du meintest die parallelen und damit konkurierenden Zugriffe auf Resourcen (in diesem Falle die Datenbank). Deswegen hast du vermutlich auch nichts zutreffendes gefunden.
 
Nochmal danke, aber jetzt mache ich das Thema doch nochmal auf, weil ich noch eine Anschlussfrage habe:

Als ich mir die paar Grundbegriffe angeeignet habe, die ich heute noch über MySql weiss, bin ich über 100 Hinweise gestolpert, die alle aussagen, dass man nach einem query ein mysql_free_result() aufrufen kann, um den Speicher freizugeben, aber das ist bei kleinen Datenmengen nicht nötig, weil der Speicher bei Scriptende sowieso automatisch freigegeben wird.
In etwa das Selbe findet sich zu mysql_connect(), es ist nicht nötig mysql_close() aufzurufen, weil die Verbindung am Scriptende automatisch geschlossen wird.

Nu kommst du mit der Erklärung, dass ein LOCK TABLE bei Verbindungsabbruch automatisch gelöst wird, was ja logisch, weil notwendig ist.
Aber da frage ich mich, sollte dann für UNLOCK TABLE nicht das Selbe gelten wie für mysql_close(), sprich kann man machen, muss man aber nicht?
 
Prinzipiell sieht das so aus, ja. Aber nur, weil man es unterlassen _kann_, ist das noch kein Grund, es auch so zu machen. Man weiß nicht, worauf das hinauslaufen kann, wenn ein Script mal wächst (Sprichwort Deadlock).

Ein sauberer Programmierer kümmert sich natürlich auch um die Aufräumarbeiten. In allen Fällen.
 
Logisch.
Ich hatte mich nur gewundert, weil bei free_result und close fast immer dabei steht, dass man es weglassen kann, aber bei UNLOCK immer dabei steht, dass man es aufrufen muss.
Ich habe mir schon lange angewöhnt auch free und close zu verwenden, schon deswegen, weil ich in ein paar Scripts auf mehrere DB´s zugreifen muss.
Auf jeden Fall nochmal danke für die Klärung.
 
Schon wieder ich, noch eine Zusatzfrage, aber zuerst mal darf ich melden, das Ganze funktioniert prima dank deiner Hilfe.
Einziger Punkt den ich nicht gefunden habe, wie lockt man mehrere Tabellen auf einmal, bzw. welches Trennzeichen gehört dazwischen?

Gefunden habe ich sowas:

Code:
LOCK TABLES `table1` READ, `table2` WRITE;

Nicht gefunden (darum vermutlich falsche Syntax hier) habe ich:

Code:
LOCK TABLES `table1`, `table2` READ, `table3`, `table4` WRITE;
 
Zurück