Doppler vermeiden
am 11.09.2007 13:20:57 von Daniel Schmidt
Hallo,
ich schreibe eine laufende Nummer in eine MySQL-DB, indem ich die letzte
Nummer in der DB abrufe, dieser eine dazuaddiere und wieder in die DB
schreibe. Das Ganze sieht momentan so aus:
$ergebnis = mysql_query("SELECT id FROM tab LIMIT 1") OR die mysql_error());
while($row = mysql_fetch_object($ergebnis)) {
$id=$row->id+1;
mysql_query("INSERT INTO tab (id) VALUES ('$id')") OR die (mysql_error());
}
Nun passiert es bei vielen Zugriffen das einige gleichzeitig zugreifen
und dieselbe id bekommen.
Nun meine Frage, lässt sich das vermeiden, dass man z.B. nur einen
Zugriff macht bzw. den Vorgang für die Abfrage und das schreiben sperrt,
z.B.:
mysql_tab_fuer_fremde_zugriffe_sperren();
.... mysql_query("SELECT ...
.... mysql_query("INSERT INTO ...
mysql_tab_sperren_aufheben();
auto_increment kommt für mich nicht in Frage
MFG Daniel
Re: Doppler vermeiden
am 11.09.2007 13:43:21 von struebig
Daniel Schmidt schrieb:
> auto_increment kommt für mich nicht in Frage
Wieso nicht?
Re: Doppler vermeiden
am 11.09.2007 13:44:11 von Andreas Kretschmer
Andreas
--
Andreas Kretschmer
Linux - weil ich es mir wert bin!
GnuPG-ID 0x3FFF606C http://wwwkeys.de.pgp.net
http://a-kretschmer.de/pict4592.jpg
Re: Doppler vermeiden
am 11.09.2007 13:47:55 von Peter Henschel
Daniel Schmidt wrote:
> Hallo,
>
> ich schreibe eine laufende Nummer in eine MySQL-DB, indem ich die letzte
> Nummer in der DB abrufe, dieser eine dazuaddiere und wieder in die DB
> schreibe. Das Ganze sieht momentan so aus:
>
>
> $ergebnis = mysql_query("SELECT id FROM tab LIMIT 1") OR die
> mysql_error()); while($row = mysql_fetch_object($ergebnis)) {
> $id=$row->id+1;
> mysql_query("INSERT INTO tab (id) VALUES ('$id')") OR die (mysql_error());
> }
>
>
> Nun passiert es bei vielen Zugriffen das einige gleichzeitig zugreifen
> und dieselbe id bekommen.
Kannst mal folgenden query probieren:
INSERT INTO tab(id) SELECT id+1 FROM tab LIMIT 1
Vielleicht hast du aber nur Probleme weil du das sortieren mittels ORDER BY
vergessen hast.
> MFG Daniel
Peter
--
http://tut.php-quake.net/
Re: Doppler vermeiden
am 11.09.2007 23:28:05 von Daniel Schmidt
> Tja, die Welt ist schlecht und früher war alles besser. Aber Hilfe naht,
> in Form von auto_increment.
Ok, zu auto_increment wird es wohl keine Alternative geben. Nun brauche
ich diese id aber als Variable in dem Script, dass diese speichert und
hier habe ich doch wieder mein Problem. Wie frage ich diesen Wert wieder
ab, ohne das mit der nächste User eine schon die nächsthöhere id
geschrieben hat?
Gruß Daniel
Re: Doppler vermeiden
am 11.09.2007 23:44:08 von Michael Fesser
..oO(Daniel Schmidt)
>Ok, zu auto_increment wird es wohl keine Alternative geben.
Gibt es. Auch in dclpd wurde noch eine angesprochen (Sequenzen).
>Nun brauche
>ich diese id aber als Variable in dem Script, dass diese speichert und
>hier habe ich doch wieder mein Problem. Wie frage ich diesen Wert wieder
>ab, ohne das mit der nächste User eine schon die nächsthöhere id
>geschrieben hat?
in SQL: LAST_INSERT_ID()
in PHP: mysql_insert_id() oder PDO->lastInsertId()
Micha
Re: Doppler vermeiden
am 11.09.2007 23:48:44 von Daniel Schmidt
> in SQL: LAST_INSERT_ID()
> in PHP: mysql_insert_id() oder PDO->lastInsertId()
Das ist ja das Problem! Und wenn zwischenzeitlich schon ein neuer User
die letzte id besetzt? Da bekomme ich doch nicht mehr die id des
aktuellen Users.
Gruß Daniel
Re: Doppler vermeiden
am 12.09.2007 00:08:09 von Sven Paulus
Daniel Schmidt wrote:
>> in SQL: LAST_INSERT_ID()
>> in PHP: mysql_insert_id() oder PDO->lastInsertId()
> Das ist ja das Problem! Und wenn zwischenzeitlich schon ein neuer User
> die letzte id besetzt? Da bekomme ich doch nicht mehr die id des
> aktuellen Users.
Doch. Die LAST_INSERT_ID() ist Connection-spezifisch.
Re: Doppler vermeiden
am 12.09.2007 08:07:14 von Claus Reibenstein
Daniel Schmidt schrieb:
>> in SQL: LAST_INSERT_ID()
>> in PHP: mysql_insert_id() oder PDO->lastInsertId()
>
> Das ist ja das Problem! Und wenn zwischenzeitlich schon ein neuer User
> die letzte id besetzt? Da bekomme ich doch nicht mehr die id des
> aktuellen Users.
Wie kommst Du denn darauf? Doku nicht gelesen?
Du bekommst immer _die_ ID geliefert, die _Du_ in _Deiner_ Session als
letztes besetzt hast. Was andere User in der Zwischenzeit mit der DB
anstellen, braucht Dich nicht zu interessieren.
Gruß. Claus
Re: Doppler vermeiden
am 12.09.2007 08:29:17 von Claus Reibenstein
Michael Fesser schrieb:
> in PHP: mysql_insert_id() oder PDO->lastInsertId()
Wieso PHP? In dieser Gruppe geht es um MySQL, nicht um PHP oder sonstige
Programmiersprachen. PHP hat eine eigene Subhierarchie in de.comp.lang
und darin auch eine eigene Gruppe für Datenbanken.
Gruß. Claus
Re: Doppler vermeiden
am 12.09.2007 15:05:24 von Dominik Echterbruch
Claus Reibenstein schrieb:
> Daniel Schmidt schrieb:
>
>>> in SQL: LAST_INSERT_ID()
>>> in PHP: mysql_insert_id() oder PDO->lastInsertId()
>> Das ist ja das Problem! Und wenn zwischenzeitlich schon ein neuer User
>> die letzte id besetzt? Da bekomme ich doch nicht mehr die id des
>> aktuellen Users.
>
> Wie kommst Du denn darauf? Doku nicht gelesen?
@Claus: In PHP (ja, ich weiß...) gibt es persistente Verbindungen, die
über verschiedene Skripte hinweg genutzt werden können. Insbesondere
auch von verschiedenen Benutzern für die selbe Aktion.
@Daniel: verwende nicht-persistente Verbindungen und alles wird gut (wie
von Claus beschrieben).
Der Verbindungsaufbau zu MySQL ist vergleichsweise günstig. Es schadet
also nicht allzuviel, eine neue Verbindung am Beginn des Skriptes zu
öffnen und am Ende des Skriptes wieder zu schließen
Grüße,
Dominik
--
Wo kämen wir denn hin, wenn jeder sagen würde wo kämen wir hin, aber
niemand gehen würde um zu sehen, wohin wir kämen, wenn wir gingen?
(Autor unbekannt)
Re: Doppler vermeiden
am 12.09.2007 16:43:10 von Sven Paulus
Dominik Echterbruch wrote:
> @Claus: In PHP (ja, ich weiß...) gibt es persistente Verbindungen, die=
=20
> über verschiedene Skripte hinweg genutzt werden können. Insbesondere=
=20
> auch von verschiedenen Benutzern für die selbe Aktion.
Aber nur sequentiell. PHP macht ja kein connection pooling, d.h. ein
PHP-"Prozess" (also z.B. ein Apache-Kindprozess mit geladenem PHP-Modul) h=
at
waehrend seine connection exklusiv fuer sich, d.h. auch waehrend der
Bearbeitung eines Requests ist dieser Verbindung immer nur von einer Insta=
nz
genutzt. Somit kann man problemlos "INSERT INTO ..." und "SELECT
LAST_INSERT_ID()" verwenden.
Wuerde das alles mit einem fixen pool von connections funktionieren, auf d=
en
die einzelnen Prozesse requestweise zugreifen, waere es ein voelliges Chao=
s,
sowas wie Transaktionen waere komplett unmoeglich.
Klar, persistente connections haben Nachteile (Zahl offener
Datenbankconnections, nicht definierter Anfangszustand, ...), aber obiges
ist keiner.
Re: Doppler vermeiden
am 12.09.2007 17:21:54 von Claus Reibenstein
Dominik Echterbruch schrieb:
> Claus Reibenstein schrieb:
>
>> Daniel Schmidt schrieb:
>>
>>> Das ist ja das Problem! Und wenn zwischenzeitlich schon ein neuer User
>>> die letzte id besetzt? Da bekomme ich doch nicht mehr die id des
>>> aktuellen Users.
>>
>> Wie kommst Du denn darauf? Doku nicht gelesen?
>
> @Claus: In PHP (ja, ich weiß...) gibt es persistente Verbindungen, die
> über verschiedene Skripte hinweg genutzt werden können. Insbesondere
> auch von verschiedenen Benutzern für die selbe Aktion.
Stimmt. An persistente Verbindungen habe ich nicht gedacht. Vermutlich
deshalb, weil ich sie bisher nie benutzt habe.
Gruß. Claus
Re: Doppler vermeiden
am 12.09.2007 19:43:07 von Michael Fesser
..oO(Claus Reibenstein)
>Michael Fesser schrieb:
>
>> in PHP: mysql_insert_id() oder PDO->lastInsertId()
>
>Wieso PHP?
Weil der OP das verwendet und somit ein ergänzender Hinweis durchaus
angebracht war.
>In dieser Gruppe geht es um MySQL, nicht um PHP oder sonstige
>Programmiersprachen. PHP hat eine eigene Subhierarchie in de.comp.lang
>und darin auch eine eigene Gruppe für Datenbanken.
Ach?!
Fup2 poster
Micha
Re: Doppler vermeiden
am 15.09.2007 10:44:06 von Thomas Rachel
Claus Reibenstein schrieb:
> Michael Fesser schrieb:
>
>> in PHP: mysql_insert_id() oder PDO->lastInsertId()
>
> Wieso PHP? In dieser Gruppe geht es um MySQL, nicht um PHP oder sonstige
> Programmiersprachen.
ACK. Man betrachte den Hinweis daher auf die gleichnamige Funktion in
der MySQL-API, die hier durchaus OnT ist.
Thomas
Re: Doppler vermeiden
am 13.11.2007 10:08:18 von Boris Stumm
Daniel Schmidt wrote:
> mysql_tab_fuer_fremde_zugriffe_sperren();
> ... mysql_query("SELECT ...
> ... mysql_query("INSERT INTO ...
> mysql_tab_sperren_aufheben();
Schon mal mit Transaktionen probiert?
http://dev.mysql.com/doc/refman/4.1/en/commit.html