Hackerboard WikiHaboBlog

[HaBo]

 
(Web-) Design und webbasierte Sprachen Tipps & Tricks, Designabgleich, HTML & Javascript, Flash, ASP, PHP, Perl/CGI...

Verständnisfrage: paralleler Insert

Diskussion: Verständnisfrage: paralleler Insert im Forum (Web-) Design und webbasierte Sprachen, in der Kategorie Web, Network & Multimedia Palace; Hallo, nehmen wir an, es existiert folgende MySQL-Tabelle (test_tabelle): Code: | id | wert | |----|-------| | 1 | alpha ...

Like Tree2Likes

Antwort
Alt 24.01.12, 17:04   #1 (permalink)
 
Registriert seit: 30.03.06
webfreak Leistung: Facit NTK
Likes: 0
Question Verständnisfrage: paralleler Insert


Hallo,

nehmen wir an, es existiert folgende MySQL-Tabelle (test_tabelle):

Code:
| id | wert  |
|----|-------|
| 1  | alpha |
| 2  | beta  |
| 3  | gamma |
Über ein PHP Script wird an 2 voneinander unabhängigen Orten der Letzte Datensatz abgefragt (wert = gamma).
Eine IF-Abfrage prüft, ob der letzte Wert tatsächlich "gamma" ist und führt bei "true" ein Query (2 Mal) aus:

PHP-Code:
if($wert=='gamma') {

mysql_query('INSERT INTO test_table (id, wert) VALUES ("4",  "delta");');


Meine Frage lautet: ist es theoretisch möglich, dass beide Inserts erfolgreich ausgeführt werden wenn das Script sozusagen an beiden Orten in der selben Nanosekunde aufgerufen wird, oder werden die SQL-Querys vom Server willkürlich in einer bestimmten Reihenfolge ausgeführt, so dass am Ende nur ein Query ausgeführt wird, weil der andere am IF gescheitert ist?

Bitte behandelt diese Frage sehr abstrakt, ich bin mir im Klaren, dass es aufgrund von Latenz usw. surreal ist, eine Abfrage zur selben Zeit an den Server zu senden. Irgendwo hatte ich mal gelesen, dass eine Tabelle immer in dem Moment für andere Zugriffe blockiert ist, wenn eine Abfrage stattfindet. Ich möchte daher wissen wie es sich verhält, wenn das Script 2 Mal zur selben Zeit aufgerufen wird

Herzlichen Dank schon mal für eure Antworten.
webfreak ist offline   Mit Zitat antworten
Alt 24.01.12, 17:47   #2 (permalink)
 
Benutzerbild von she3p
 
Registriert seit: 07.05.07
she3p Leistung: 8086
Likes: 18
Standard

Zitat:
Zitat von webfreak Beitrag anzeigen
Meine Frage lautet: ist es theoretisch möglich, dass beide Inserts erfolgreich ausgeführt werden wenn das Script sozusagen an beiden Orten in der selben Nanosekunde aufgerufen wird, oder werden die SQL-Querys vom Server willkürlich in einer bestimmten Reihenfolge ausgeführt, so dass am Ende nur ein Query ausgeführt wird, weil der andere am IF gescheitert ist?
Kurze Antwort: Ja, das ist möglich.
Dafür gibt es allerdings Transaktionen.
webfreak likes this.
__________________
she3p ist offline   Mit Zitat antworten
   
HaBOT
 

Werbung ist gerade online    
Alt 24.01.12, 18:27   #3 (permalink)
Themenstarter
 
Registriert seit: 30.03.06
webfreak Leistung: Facit NTK
Likes: 0
Standard

Läuft das auf das selbe hinaus wie LOCK TABLES und UNLOCK TABLES?
webfreak ist offline   Mit Zitat antworten
Alt 24.01.12, 19:13   #4 (permalink)
Moderator
 
Benutzerbild von bitmuncher
 
Registriert seit: 30.09.06
bitmuncher Leistung: Opteronbitmuncher Leistung: Opteronbitmuncher Leistung: Opteronbitmuncher Leistung: Opteronbitmuncher Leistung: Opteronbitmuncher Leistung: Opteron
Likes: 378
Standard

Zitat:
Zitat von webfreak Beitrag anzeigen
Läuft das auf das selbe hinaus wie LOCK TABLES und UNLOCK TABLES?
Nicht ganz. Bei einer Transaktion werden die Queries unterbrechungsfrei ausgeführt, die innerhalb der Transaktion sind. Bei einem Lock-Tables kann auch nur der Lese- oder der Schreibzugriff blockiert werden. Wird z.B. nur der Schreibzugriff blockiert, können Lesezugriff noch stattfinden.
webfreak likes this.
__________________
Mein Blog - Mein Job - Diaspora

Der Ring uns zu knechten besteht aus 12 Sternen auf blauem Grund.

Neue Beiträge im Habo via Twitter - Das HaBo auf FB - Das HaBo bei G+
bitmuncher ist offline   Mit Zitat antworten
Alt 24.01.12, 19:34   #5 (permalink)
Themenstarter
 
Registriert seit: 30.03.06
webfreak Leistung: Facit NTK
Likes: 0
Standard

Okay, ich habe mich in die Sache noch etwas reingelesen. Für meinen Fall wäre LOCK TABLES ausreichend, allerdings frage ich mich immer noch, wie die Datenbank entscheidet welcher Query Vorrang erhält und welcher eben als zweites ausgeführt wird. Nicht dass es wichtig wäre, weil in meinem Beispiel sowieso beide gleich sind.. Aber würde mich interessieren wie das technisch gelöst ist.
webfreak ist offline   Mit Zitat antworten
Alt 24.01.12, 19:53   #6 (permalink)
Moderator
 
Benutzerbild von bitmuncher
 
Registriert seit: 30.09.06
bitmuncher Leistung: Opteronbitmuncher Leistung: Opteronbitmuncher Leistung: Opteronbitmuncher Leistung: Opteronbitmuncher Leistung: Opteronbitmuncher Leistung: Opteron
Likes: 378
Standard

Das wird anhand der Prozess-Queue gelöst. Es können niemals beide Prozesse an der gleichen Stelle in der Queue stehen. Jener, der also zuerst Rechenzeit bekommt um in der Queue zu landen, wird vorrangig behandelt.
__________________
Mein Blog - Mein Job - Diaspora

Der Ring uns zu knechten besteht aus 12 Sternen auf blauem Grund.

Neue Beiträge im Habo via Twitter - Das HaBo auf FB - Das HaBo bei G+
bitmuncher ist offline   Mit Zitat antworten
Alt 24.01.12, 20:10   #7 (permalink)
Themenstarter
 
Registriert seit: 30.03.06
webfreak Leistung: Facit NTK
Likes: 0
Standard

Okay, das klingt logisch. Ich werde das vllt. mal testen, indem ich meinem PHP-Script ein sleep() gebe und in der Zeit eine andere Abfrage starte

Gerade ist mir eingefallen, dass es evtl. im Beispiel auch zielführend wäre, der Spalte "wert" einen Unique-Index zu geben. Ist halt die Frage was passiert, wenn in diesem Fall beide Abfragen gleichzeitig beim Server ankommen. Um mal dein Stichwort "Rechenzeit" aufzugreifen: da würde dann ein Query bevorteilt werden und das Problem hätte sich durch den Unique erledigt (?)
webfreak ist offline   Mit Zitat antworten
Alt 24.01.12, 22:57   #8 (permalink)
Moderator
 
Benutzerbild von bitmuncher
 
Registriert seit: 30.09.06
bitmuncher Leistung: Opteronbitmuncher Leistung: Opteronbitmuncher Leistung: Opteronbitmuncher Leistung: Opteronbitmuncher Leistung: Opteronbitmuncher Leistung: Opteron
Likes: 378
Standard

Zitat:
Zitat von webfreak Beitrag anzeigen
Um mal dein Stichwort "Rechenzeit" aufzugreifen: da würde dann ein Query bevorteilt werden und das Problem hätte sich durch den Unique erledigt (?)
Ja, genau so. Allerdings solltest du dann auch noch eine auto_increment setzen, weil unique nicht automatisch aufsteigend bedeuten muss. Das als zweites ausgeführte Query könnte also bei einem unique ohne auto_increment auch kleiner sein als das erste, wodurch die Reihenfolge nicht mehr erkennbar wäre.
__________________
Mein Blog - Mein Job - Diaspora

Der Ring uns zu knechten besteht aus 12 Sternen auf blauem Grund.

Neue Beiträge im Habo via Twitter - Das HaBo auf FB - Das HaBo bei G+
bitmuncher ist offline   Mit Zitat antworten
Alt 25.01.12, 02:11   #9 (permalink)
Senior Member
 
Benutzerbild von t3rr0r.bYt3
 
Registriert seit: 07.01.03
t3rr0r.bYt3 Leistung: Z3
Likes: 13
Standard

Zitat:
Bei einer Transaktion werden die Queries unterbrechungsfrei ausgeführt, die innerhalb der Transaktion sind
Nur logisch, aber nicht wirklich. Das Ergebnis sieht aus, als wären sie serialisiert worden, tatsächlich laufen sie aber (soweit möglich) parallel ab.
t3rr0r.bYt3 ist offline   Mit Zitat antworten
Alt 25.01.12, 16:52   #10 (permalink)
Themenstarter
 
Registriert seit: 30.03.06
webfreak Leistung: Facit NTK
Likes: 0
Standard

Danke für eure umfassende Hilfe, ich werde wohl direkt die Transaktionen von MySQL nutzen:

PHP-Code:
mysql_query('SET autocommit=0;');
mysql_query('START TRANSACTION;');
mysql_query('LOCK TABLES test WRITE;');

// query [...]

mysql_query('COMMIT;');
mysql_query('UNLOCK TABLES;'); 
Funktioniert erstaunlich gut, allerdings muss man vorher der Tabelle den Typ "InnoDB" geben. Wenn ich jetzt noch der Spalte "wert" einen Unique-Index gebe, dürfte ich vor der benannten doppelten Ausführung sicher sein

Geändert von webfreak (25.01.12 um 16:58 Uhr)
webfreak ist offline   Mit Zitat antworten
Alt 25.01.12, 18:03   #11 (permalink)
Senior Member
 
Benutzerbild von t3rr0r.bYt3
 
Registriert seit: 07.01.03
t3rr0r.bYt3 Leistung: Z3
Likes: 13
Standard

Bedenke, dass du mit einem LOCK TABLES parallele Schreibzugriffe auf die Tabelle komplett unterbindest. Wenn (parallele) Performance eine Rolle spielt, ist das eine schlechte Wahl.
t3rr0r.bYt3 ist offline   Mit Zitat antworten
Alt 25.01.12, 19:33   #12 (permalink)
Themenstarter
 
Registriert seit: 30.03.06
webfreak Leistung: Facit NTK
Likes: 0
Standard

Zitat:
Zitat von t3rr0r.bYt3 Beitrag anzeigen
Bedenke, dass du mit einem LOCK TABLES parallele Schreibzugriffe auf die Tabelle komplett unterbindest. Wenn (parallele) Performance eine Rolle spielt, ist das eine schlechte Wahl.
In diesem Fall ist es gewollt
webfreak ist offline   Mit Zitat antworten
Alt 25.01.12, 20:18   #13 (permalink)
Senior Member
 
Benutzerbild von t3rr0r.bYt3
 
Registriert seit: 07.01.03
t3rr0r.bYt3 Leistung: Z3
Likes: 13
Standard

Wieso? Das sperrt insbesondere auch Updates und Deletes von völlig unbetroffenen Zeilen aus.
t3rr0r.bYt3 ist offline   Mit Zitat antworten
Alt 27.01.12, 08:40   #14 (permalink)
Member of Honour
 
Registriert seit: 11.09.03
Watchme Leistung: Z3
Likes: 2
Standard

wobei man sich auch eine "Sperrtabelle" machen könnte.
Wenn man nun von 2 Prozessen ausgeht, die gleichzeitig gestartet werden und deren Logik so aussieht:
Code:
Originale Speichertabelle
| id | wert  |
|----|-------|
| 1  | alpha |
| 2  | beta  |
| 3  | gamma |

Sperrtabelle
| id |
|----|
| 4  |
dann könnte man mit der Logik: höchste ID = {höchste ID aus origTab UND Sperrtab} dafür sorgen, dass nie 2 Prozesse auf dieselbe ID schreiben.
Natürlich muss der Eintrag in der SperrTab ein COMMIT bekommen, und man muss hinterher die SperrTab wieder aufräumen.
Watchme ist offline   Mit Zitat antworten
Alt 27.01.12, 08:46   #15 (permalink)
 
Registriert seit: 17.01.06
Oi!Alex Leistung: 8086
Likes: 7
Standard

Wenn so wieso beide Prozesse das gleiche schreiben kann man auch mit REPLACE INTO arbeiten.

Gesendet von meinem HTC Desire mit Tapatalk
Oi!Alex ist offline   Mit Zitat antworten
Antwort
   

Werbung ist gerade online    

[HaBo] » Web, Network & Multimedia Palace » (Web-) Design und webbasierte Sprachen » SQL Verständnisfrage: paralleler Insert
Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind aus
Pingbacks sind aus
Refbacks sind aus


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
SQL SELECT, INSERT vs INSERT Inliferty (Web-) Design und webbasierte Sprachen 1 29.07.11 20:16
php -> insert into klappt nicht? Oo _fux_ (Web-) Design und webbasierte Sprachen 12 07.11.09 16:37
C++ Rekursionsfunktion / insert item _fux_ Code Kitchen 12 08.09.08 17:39
mysql mehrere insert Dawen Applikationen 0 17.04.08 17:50
Verständnisfrage zu md5 crusaderv83 Cryptography & Encryption 16 29.08.07 22:31


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61