login  Naam:   Wachtwoord: 
Registreer je!
 Forum

mysql_insert_id en concurrency

Offline TomJansen - 21/10/2008 16:20
Avatar van TomJansenNieuw lid Neem een tabel met de kolommen `id` en `data`.
De `id` kolom is AUTOINCREMENT.

In een webpagina waar de bezoeker iets kan posten, voeg ik een record toe:
  1. mysql_query( "INSERT INTO tabel (data) VALUES('$fnord');" );

En dan wil ik de `id` weten, van het zojuist toegevoegde record...


Is dit veilig, wanneer meerdere bezoekers tegelijk kunnen posten? Dus wanneer het script door meerdere threads tegelijkertijd wordt uitgevoerd?

(Het is denkbaar dat thread A de INSERT-query uitvoert, vervolgens thread B de INSERT-query uitvoert, en vervolgens thread A de id van thread B krijgt.)

De documentatie zegt:
For LAST_INSERT_ID(), the most recently generated ID is maintained in the server on a per-connection basis. It is not changed by another client.

Betekent dit, dat deze methode alleen veilig is als we geen persistente connecties gebruiken?
Dus dat het met:veilig is,

en dat het met:pas veilig is als we een LOCK gebruiken?

(Ik gebruik een persistente connectie voor mijn website, want het lijkt me zo dat bij een website, het gebruik van een persistente connectie, een betere performance oplevert dan dat er voor elke pageview opnieuw een connectie wordt gemaakt.)

7 antwoorden

Gesponsorde links
Offline Joost - 21/10/2008 17:44
Avatar van Joost PHP expert Een query op mijn server duurt 0,0005 seconden, vanuit PHPMyAdmin.
Er bestaat natuurlijk nog wel een kans dat je elkaars ID overneemt, maar die kans is erg klein 
Offline Kr4nKz1n - 21/10/2008 18:06
Avatar van Kr4nKz1n Onbekend Dit is wel veilig hoor. Of denk je dat je een website zoals hyves krijgt?

Als je het toch niet veilig vindt, maak je daarna een SELECT query ofzo 
Offline TomJansen - 22/10/2008 13:04
Avatar van TomJansen Nieuw lid Thanks voor de reacties!
Een kleine kans is niet klein genoeg; garantie daar kan je op bouwen  Of is dat geen gezonde dosis paranoia ...
Het zal een erg druk bezochte site worden.

Maar weet iemand of dit afhangt van het wel of niet gebruiken van persistente connecties (mysql_pconnect) ?

Als dat zo is, dan overweeg ik om voor de meeste pagina's mysql_pconnect te gebruiken, maar voor de pagina's die iets INSERTen de gewone mysql_connect.

Kr4nKz1n schreef:
Als je het toch niet veilig vindt, maak je daarna een SELECT query ofzo 
... waarbij je dus controleert op andere velden dan de `id`.
Offline Kr4nKz1n - 22/10/2008 18:19
Avatar van Kr4nKz1n Onbekend
  1. Mysql_Query("SELECT id FROM tabel WHERE username='".$_POST['username']."' ORDER BY id DESC LIMIT 0,1");


Geen idee waar voor het is dus dan maar de DESC LIMIT 0,1 erbij
Offline Martijn - 22/10/2008 20:27
Avatar van Martijn Crew PHP pconnect NIET gebruiken Daar heb je alleen wat aan als je specifieke problemen begint te krijgen met je verbinding.

Maar om je vraag te beantwoorden, ik denk niet dat de kans dat het gebeurd desdanig groot is dat je er iets mee moet doen. De select kan namelijk ook worden uitgevoerd, en daarna nog een insert hebben door iemand anders 
Offline Wim - 22/10/2008 22:09
Avatar van Wim Crew algemeen ik citeer uit je eigen post:
Citaat:
For LAST_INSERT_ID(), the most recently generated ID is maintained in the server on a per-connection basis. It is not changed by another client.


maw: insert van client 1: tijd: +0s
insert van client 2: tijd +1s
get id van client 2: tijd +2s
get id van client 1: tijd +3s

zoals je ziet heb je nu de situatie die jij "niet wilt". Maar eigenlijk maakt dit niet uit, aangezien het per connectie bekeken wordt => beide geven dus altijd een door jou gewenst resultaat
Offline TomJansen - 23/10/2008 17:30 (laatste wijziging 24/10/2008 17:33)
Avatar van TomJansen Nieuw lid Wederom hartelijk dank voor de reakties mensen!

Kr4nKz1n schreef:
"SELECT id FROM tabel WHERE username='".$_POST['username'] ...
Stel dat elke milliseconde telt...

Vandaar dat ik eerst voor pconnect had gekozen, want ik vind het eigenlijk absurd dat er bij elke pageview opnieuw een verbinding moet worden geïnitialiseerd.

wimmarien schreef:
ik citeer uit je eigen post:
Citaat:
For
LAST_INSERT_ID(), the most recently generated ID is maintained in the server on a per-connection basis. It is not changed by another client.

maw: insert van client 1: tijd: +0s
insert van client 2: tijd +1s
get id van client 2: tijd +2s
get id van client 1: tijd +3s

zoals je ziet heb je nu de situatie die jij "niet wilt". Maar eigenlijk maakt dit niet uit, aangezien het per connectie bekeken wordt => beide geven dus altijd een door jou gewenst resultaat
Ja, maar let op: dat is vanuit MySQL-perspektief. De "client" is dan PHP.
Nu is het dus de vraag of verschillende "webclients" (requests die tegelijk afgehandeld worden) misschien toch niet dezelfde MySQL-connectie gebruiken...

Nou las ik (hier) dat elke thread/proces zijn eigen connection-pool bijhoudt; zowel met connect als met pconnect.
Vandaar dat het gebruik van pconnect juist meer openstaande verbindingen oplevert dan gewoon connect; zelfs zoveel dat alleen al het bijhouden van die verbindingen op een shared server te veel werkgeheugen kan vreten!

Als elke thread zijn eigen connection-pool bijhoudt, dan zou het probleem met mysql_insert_id() inderdaad nooit kunnen voorkomen.

Maar, hier:
http://www.expe...76904.html
... zit dus iemand met dat probleem en daar wordt toch gezegd dat het met pconnect te maken heeft!

Dus ik ben er nog steeds niet uit; denk dat ik gewoon connect gebruik en dan wel zal zien.
Misschien interessante topic voor verdere diskussie ... anders in elk geval bedankt voor de suggesties!
Gesponsorde links
Dit onderwerp is gesloten.
Actieve forumberichten
© 2002-2024 Sitemasters.be - Regels - Laadtijd: 0.228s