Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: MySQL LAST_INSERT_ID()
Forum PHP.pl > Forum > Bazy danych
ksenonlogin
Witam

Od jakiegoś czasu nurtuje mnie pewna sprawa z funkcją mysql_insert_id(). Czy gdy pobieram id nowo wstawionego prze zemnie rekordu, to mam pewność że jest to id tego rekordu?

Może dokładnie na takiej sytuacji:

Załóżmy że użytkownik "A" wstawia nowy rekord do tabeli (niech będzie że auto_increment nadał rekordowi id: "2") i pobiera id tego rekordu za pomocą funkcji: mysql_insert_id(), funkcja ta zwraca wtedy id rekordu: "2",
a w tym samym czasie wykonuje tą samą czynność użytkownik "B" który wstawił rekord (z nadanym id: "3"), a więc chodzi mi o to:

Czy dane sytuacja może się skrzyżować?, w momencie gdy użytkownik "A" wstawia rekord, a potem pobiera numer id powstaje jakaś luka czasowa między tymi czynnościami, i gdy użytkownik "B" wstawi rekord w tym czasie (w czasie tej przerwy między wstawieniem a pobraniem id), to użytkownik "A" otrzyma id swojego rekordu czy id rekordu innego użytkownika (użytkownika "B")?

Jeżeli taka sytuacja może się zdarzyć to proszę o podanie sposobu który pozwoli tego uniknąć.



Pozdrawiam
wookieb
Nie dubluj tematów. Jeden w zupełności wystarczy.
ksenonlogin
Cytat(wookieb @ 29.10.2011, 12:37:26 ) *
Nie dubluj tematów. Jeden w zupełności wystarczy.

Nie wiedziałem gdzie go umieścić, ponieważ jest to funkcja PHP ale tyczy się Baz danych
croc
Ciekawe pytanie. Wydaje mi się, choć nie wiem tego na pewno, że funkcja mysql_insert_id zwraca zawsze ostatni ID wstawiony przez Ciebie. Dlatego, że jako parametr opcjonalny przyjmuje identyfikator połączenia, a gdy go nie dostaje, analizuje po prostu ostatnie połączenie. Operacje na danych są powiązane z konkretnymi połączeniami, więc moim zdaniem możesz śmiało używać tej funkcji.
ksenonlogin
Cytat(croc @ 29.10.2011, 14:03:18 ) *
Ciekawe pytanie. Wydaje mi się, choć nie wiem tego na pewno, że funkcja mysql_insert_id zwraca zawsze ostatni ID wstawiony przez Ciebie. Dlatego, że jako parametr opcjonalny przyjmuje identyfikator połączenia, a gdy go nie dostaje, analizuje po prostu ostatnie połączenie. Operacje na danych są powiązane z konkretnymi połączeniami, więc moim zdaniem możesz śmiało używać tej funkcji.



Załóżmy że jakimś cudem identyfikator połączenia zostanie zagubiony (mój identyfikator), bądź przez jakiś błąd tego identyfikatora nie dostanie to będzie analizowane połączenie ostatnie i pobierze błędny klucz rekordu wstawionego prze ze mnie tak?

niżej:

gdy za pierwszym razem wszystko sie uda a za drugim nie to poda id z pierwszego razu tak?

<?php
mysql_connect('localhost', 'uzytkownik', 'haslo') or
die('Nie można się połączyć');
mysql_select_db('baza');

mysql_query("INSERT INTO mytable (uzytkownik) values ('ksenonlogin1')");
printf ("Ostatnio dodany rekord ma id %d\n", mysql_insert_id());


mysql_query("INSERT INTO mytable (uzytkownik) values ('ksenonlogin2')");
printf ("Ostatnio dodany rekord ma id %d\n", mysql_insert_id());


?>
croc
Podoba mi się Twój wnikliwy tok myślenia. Myślę, że najprostszym sposobem upewnienia się jak działa mysql_insert_id jest po prostu połączenie się z bazą i użycie tej funkcji bez wstawiania jakiegokolwiek zapytania przed nią. Jakieś rekordy były przecież wcześniej dodane.
ksenonlogin
Cytat(croc @ 29.10.2011, 15:49:28 ) *
Podoba mi się Twój wnikliwy tok myślenia. Myślę, że najprostszym sposobem upewnienia się jak działa mysql_insert_id jest po prostu połączenie się z bazą i użycie tej funkcji bez wstawiania jakiegokolwiek zapytania przed nią. Jakieś rekordy były przecież wcześniej dodane.


Dzięki wielkie, za dużo negatywnych możliwości rozpatrywałem, sprawdziłem i w przypadku braku identyfikatora połączenia, szuka ostatniego otwartego połączenia (mojego połączenia dla jednego zapytania) gdy go nie znajdzie zwraca domyślną wartość "0", po prostu dla każdego połączenia mamy indywidualny klucz i za każdym razem połączenie jest przecież zamykane gdy algorytm się posypie w jakimś bicie to połączenia między "zapytaniem" a "bazą" się nie pokrywają czyli połączenie już nie trwa czyli "0"

Jeszcze raz wielkie dzięki ;-)
maly_swd
Z tego co ja sprawdzalem, to jesli nie podasz parametru do mysql_insert_id to uzyje ona ostatniego TWOJEGO polaczenia w skrypcie.

Tzn w 1 skrypcie mozesz miec np 5 roznych ID_polaczen do bazy i jesli zrobisz na kazdym inserta i bedziesz chcial odczytac INSERT_ID podajac polaczenie to poda Ci dla niego. Jesli natomiast nic nie podasz dostaniesz INSERT_ID z ostatniego TWOJEGO polaczenia.

A jak nie bylo zadnego TWOJEGO polaczenia to sie "wywali";)
croc
Cytat(maly_swd @ 4.11.2011, 12:07:31 ) *
Z tego co ja sprawdzalem, to jesli nie podasz parametru do mysql_insert_id to uzyje ona ostatniego TWOJEGO polaczenia w skrypcie.

Nie trzeba sprawdzać, w manualu jest wszystko wyjaśnione.
xdev
Może się zdarzyć tak, że podczas długiej kwerendy stracisz połączenie do bazy (timeout)... i jeśli możesz się połączyć przy wykorzystaniu mysql_connect() bez parametrów to ta funkcja to zrobi i zwróci zero. Więc najpierw się trzeba upewnić, że mysql_connect nie może tego zrobić.

Ogólnie zawsze działa dobrze. Lepiej jednak zrobić SELECT LAST_INSERT_ID(); bo funkcja z PHP zwraca integer i mogą być problemy z dużymi wartościami (typu ID z FB, bo to BIGINTy)

Jak chcesz mieć 100% pewności to musisz się upewnić, że mysql_connect bez parametrów nie może połączyć się z bazą a całość wrzucić w transakcję.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.